# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['strawberry_django_dataloaders', 'strawberry_django_dataloaders.core']

package_data = \
{'': ['*']}

install_requires = \
['Django>=3.2', 'strawberry-graphql-django>=0.4,<0.5']

setup_kwargs = {
    'name': 'strawberry-django-dataloaders',
    'version': '0.1.1',
    'description': 'A set of tools for using dataloaders with Django and Strawberry GraphQL.',
    'long_description': '# Dataloaders for Django and Strawberry\nA set of tools for using dataloaders with [Django](https://github.com/django/django) \nand [Strawberry](https://github.com/strawberry-graphql/strawberry) without unnecessary boilerplate.\n\n## Installation\n\n```bash\nTODO\n```\n\n\n## Usage & examples\nThis package provides 3 levels of generating dataloaders, each offering higher level of abstraction\nthan the previous one.\n### Models definition\nDefinition of models used in the examples.\n```python\nfrom django.db import models\n\nclass Fruit(models.Model):\n    plant = models.OneToOneField("FruitPlant", ...)\n    color = models.ForeignKey("Color", ...)\n    varieties = models.ManyToManyField("FruitVariety", ..., related_name="fruits")\n\nclass FruitEater(models.Model):\n    favourite_fruit = models.ForeignKey("Fruit", ..., related_name="eaters")\n```\n### Level 1: Simple dataloader\nOn the first level, we\'re defining and using different dataloader for each relationship.\n#### One-to-one and Many-to-one relationship\n1. Define the dataloaders\n```python\nfrom strawberry_django_dataloaders import dataloaders\n\nclass ColorPKDataLoader(dataloaders.BasicPKDataLoader):\n    model = models.Color\n\n\nclass FruitPlantPKDataLoader(dataloaders.BasicPKDataLoader):\n    model = models.FruitPlant\n```\n2. Use them when defining the Strawberry type\n```python\n@strawberry_django.type(models.Fruit)\nclass FruitType:\n    id: strawberry.auto\n    \n    ### ↓ HERE ↓ ###\n    @strawberry.field\n    async def color(self: "models.Fruit", info: "Info") -> ColorType | None:\n        return await dataloaders.ColorPKDataLoader(context=info.context).load(self.color_id)\n\n    @strawberry.field\n    async def plant(self: "models.Fruit", info: "Info") -> FruitPlantType | None:\n        return await dataloaders.FruitPlantPKDataLoader(context=info.context).load(self.plant_id)\n```\n\n#### One-to-many relationship\n1. Define the dataloader\n```python\nfrom strawberry_django_dataloaders import dataloaders\n\nclass FruitEatersReverseFKDataLoader(dataloaders.BasicReverseFKDataLoader):\n    model = models.FruitEater\n    reverse_path = "favourite_fruit_id"   # <-- is the "reverse" FK field from FruitEater to Fruit model\n```\n2. Use it when defining the Strawberry type\n```python\n@strawberry_django.type(models.Fruit)\nclass FruitType:\n    id: strawberry.auto\n    \n    ### ↓ HERE ↓ ###\n    @strawberry.field\n    async def eaters(self: "models.Fruit", info: "Info") -> list[FruitEaterType]:\n        return await dataloaders.FruitEatersReverseFKDataLoader(context=info.context).load(self.pk)\n```\n\n### Level 2: Dataloader factories\nWhen using the dataloader factories, we no longer need to define a dataloader for each relation.\n```python\nfrom strawberry_django_dataloaders import factories\n\n\n@strawberry_django.type(models.Fruit)\nclass FruitTypeDataLoaderFactories:\n    id: strawberry.auto\n    \n    ### ↓ ONE-TO-ONE AND MANY-TO-ONE DATALOADERS ↓ ###\n    @strawberry.field\n    async def color(self: "models.Fruit", info: "Info") -> ColorType | None:\n        loader = factories.PKDataLoaderFactory.get_loader_class("tests.Color")\n        return await loader(context=info.context).load(self.color_id)\n\n    @strawberry.field\n    async def plant(self: "models.Fruit", info: "Info") -> FruitPlantType | None:\n        loader = factories.PKDataLoaderFactory.get_loader_class("tests.FruitPlant")\n        return await loader(context=info.context).load(self.plant_id)\n    \n    ### ↓ ONE-TO-MANY DATALOADER ↓ ###\n    @strawberry.field\n    async def eaters(self: "models.Fruit", info: "Info") -> list[FruitEaterType]:\n        loader = factories.ReverseFKDataLoaderFactory.get_loader_class(\n            "tests.FruitEater",\n            reverse_path="favourite_fruit_id",\n        )\n        return await loader(context=info.context).load(self.color_id)\n```\n\n### Level 3: Auto dataloader field\nA field used in a similar fashion as native Django strawberry field, but it has auto-defined correct dataloader handler\nbased on the field relationship.\n```python\nfrom strawberry_django_dataloaders import fields \n\n@strawberry_django.type(models.Fruit)\nclass FruitTypeAutoDataLoaderFields:\n    id: strawberry.auto\n    color: ColorType = fields.auto_dataloader_field()\n    plant: FruitPlantType = fields.auto_dataloader_field()\n    varieties: list[FruitVarietyType] = fields.auto_dataloader_field()\n    eaters: list[FruitEaterType] = fields.auto_dataloader_field()\n```\n\n## Contributing\nPull requests for any improvements are welcome.\n\n[Poetry](https://github.com/sdispater/poetry) is used to manage dependencies.\nTo get started follow these steps:\n\n```shell\ngit clone https://github.com/VojtechPetru/strawberry-django-dataloaders\ncd strawberry-django-dataloaders\npoetry install\npoetry run pytest\n```\n\n### Pre commit\n\nWe have a configuration for\n[pre-commit](https://github.com/pre-commit/pre-commit), to add the hook run the\nfollowing command:\n\n```shell\npre-commit install\n```\n\n## Links\n- Inspired and builds on top of a great article at: https://alexcleduc.com/posts/graphql-dataloader-composition/\n- Repository: https://github.com/VojtechPetru/strawberry-django-dataloaders\n- Issue tracker: https://github.com/VojtechPetru/strawberry-django-dataloaders/issues. \nIn case of sensitive bugs (e.g. security vulnerabilities) please contact me at _petru.vojtech@gmail.com_ directly.\n\n## Known issues/shortcomings\n- `Many-to-many` relation is currently not supported.\n',
    'author': 'vojtech',
    'author_email': 'petru.vojtech@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.9,<4.0',
}


setup(**setup_kwargs)
