%global _empty_manifest_terminate_build 0 Name: python-graphene-django-plus Version: 5.0 Release: 1 Summary: Tools to easily create permissioned CRUD endpoints in graphene. License: MIT URL: https://github.com/0soft/graphene-django-plus Source0: https://mirrors.nju.edu.cn/pypi/web/packages/a9/4e/aea4f90e04e6d7d8c2db0296caca57f23128deddc8378f121a160ee8f3a3/graphene_django_plus-5.0.tar.gz BuildArch: noarch %description # graphene-django-plus [![build status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2F0soft%2Fgraphene-django-plus%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/0soft/graphene-django-plus/goto?ref=master) [![docs status](https://img.shields.io/readthedocs/graphene-django-plus.svg)](https://graphene-django-plus.readthedocs.io) [![coverage](https://img.shields.io/codecov/c/github/0soft/graphene-django-plus.svg)](https://codecov.io/gh/0soft/graphene-django-plus) [![PyPI version](https://img.shields.io/pypi/v/graphene-django-plus.svg)](https://pypi.org/project/graphene-django-plus/) ![python version](https://img.shields.io/pypi/pyversions/graphene-django-plus.svg) ![django version](https://img.shields.io/pypi/djversions/graphene-django-plus.svg) > ## DEPRECATION WARNING > > Graphene itself is abandoned and most users are migrating to other better alternatives, like > [strawberry](https://github.com/strawberry-graphql/strawberry). > > For that reason this lib is being deprecated and new features will no longer be developed for it. > Maintenance is still going to happen and PRs are still welcomed though. > > For anyone looking for alternatives, I created > [strawberry-django-plus](https://github.com/blb-ventures/strawberry-django-plus) to use not > only as a migration path to the projects I maintain, but also to add even more awesome features. > Be sure to check it out! Tools to easily create permissioned CRUD endpoints in [graphene-django](https://github.com/graphql-python/graphene-django). ## Install ```bash pip install graphene-django-plus ``` To make use of everything this lib has to offer, it is recommended to install both [graphene-django-optimizer](https://github.com/tfoxy/graphene-django-optimizer) and [django-guardian](https://github.com/django-guardian/django-guardian). ```bash pip install graphene-django-optimizer django-guardian ``` ## What it does - Provides some base types for Django Models to improve querying them with: - Unauthenticated user handling - Automatic optimization using [graphene-django-optimizer](https://github.com/tfoxy/graphene-django-optimizer) - Permission handling for queries using the default [django permission system](https://docs.djangoproject.com/en/2.2/topics/auth/default/#topic-authorization) - Object permission handling for queries using [django guardian](https://github.com/django-guardian/django-guardian) - Relay id conversion so querying can use the global id instead of the model's id - Provides a set of complete and simple CRUD mutations with: - Unauthenticated user handling - Permission handling using the default [django permission system](https://docs.djangoproject.com/en/2.2/topics/auth/default/#topic-authorization) - Object permission handling using [django guardian](https://github.com/django-guardian/django-guardian) - Automatic input generation based on the model (no need to write your own input type or use `django forms` and `drf serializers`) - Automatic model validation based on the model's validators - Very simple to create some quick CRUD endpoints for your models - Easy to extend and override functionalities - File upload handling ## What is included Check the [docs](https://graphene-django-plus.readthedocs.io) for a complete api documentation. ### Models - `graphene_django_plus.models.GuardedModel`: A django model that can be used either directly or as a mixin. It will provide a `.has_perm` method and a `.objects.for_user` that will be used by `ModelType` described below to check for object permissions. ### Types and Queries - `graphene_django_plus.types.ModelType`: This enchances `graphene_django_plus.DjangoModelType` by doing some automatic `prefetch` optimization on setup and also checking for objects permissions on queries when it inherits from `GuardedModel`. - `graphene_django_plus.fields.CountableConnection`: This enchances `graphene.relay.Connection` to provide a `total_count` attribute. Here is an example describing how to use those: ```py import graphene from graphene import relay from graphene_django.fields import DjangoConnectionField from graphene_django_plus.models import GuardedModel from graphene_django_plus.types import ModelType from graphene_django_plus.fields import CountableConnection class MyModel(GuardedModel): class Meta: # guardian permissions for this model permissions = [ ('can_read', "Can read the this object's info."), ] name = models.CharField(max_length=255) class MyModelType(ModelType): class Meta: model = MyModel interfaces = [relay.Node] # Use our CountableConnection connection_class = CountableConnection # When adding this to a query, only objects with a `can_read` # permission to the request's user will be allowed to return to him # Note that `can_read` was defined in the model. # If the model doesn't inherid from `GuardedModel`, `guardian` is not # installed or this list is empty, any object will be allowed. # This is empty by default object_permissions = [ 'can_read', ] # If unauthenticated users should be allowed to retrieve any object # of this type. This is not dependent on `GuardedModel` and neither # `guardian` and is defined as `False` by default public = False # A list of Django model permissions to check. Different from # object_permissions, this uses the basic Django's permission system # and thus is not dependent on `GuardedModel` and neither `guardian`. # This is an empty list by default. permissions = [] class Query(graphene.ObjectType): my_models = DjangoConnectionField(MyModelType) my_model = relay.Node.Field(MyModelType) ``` This can be queried like: ```graphql # All objects that the user has permission to see query { myModels { totalCount edges { node { id name } } } } # Single object if the user has permission to see it query { myModel(id: "") { id name } } ``` ### Mutations - `graphene_django_plus.mutations.BaseMutation`: Base mutation using `relay` and some basic permission checking. Just override its `.perform_mutation` to perform the mutation. - `graphene_django_plus.mutations.ModelMutation`: Model mutation capable of both creating and updating a model based on the existence of an `id` attribute in the input. All the model's fields will be automatically read from Django, inserted in the input type and validated. - `graphene_django_plus.mutations.ModelCreateMutation`: A `ModelMutation` enforcing a "create only" rule by excluding the `id` field from the input. - `graphene_django_plus.mutations.ModelUpdateMutation`: A `ModelMutation` enforcing a "update only" rule by making the `id` field required in the input. - `graphene_django_plus.mutations.ModelDeleteMutation`: A mutation that will receive only the model's id and will delete it (if given permission, of course). Here is an example describing how to use those: ```py import graphene from graphene import relay from graphene_django_plus.models import GuardedModel from graphene_django_plus.types import ModelType from graphene_django_plus.mutations import ( ModelCreateMutation, ModelUpdateMutation, ModelDeleteMutation, ) class MyModel(GuardedModel): class Meta: # guardian permissions for this model permissions = [ ('can_write', "Can update this object's info."), ] name = models.CharField(max_length=255) class MyModelType(ModelType): class Meta: model = MyModel interfaces = [relay.Node] class MyModelUpdateMutation(ModelUpdateMutation): class Meta: model = MyModel # Make sure only users with the given permissions can modify the # object. # If the model doesn't inherid from `GuardedModel`, `guardian` is not # installed on this list is empty, any object will be allowed. # This is empty by default. object_permissions = [ 'can_write', ] # If unauthenticated users should be allowed to retrieve any object # of this type. This is not dependent on `GuardedModel` and neither # `guardian` and is defined as `False` by default public = False # A list of Django model permissions to check. Different from # object_permissions, this uses the basic Django's permission system # and thus is not dependent on `GuardedModel` and neither `guardian`. # This is an empty list by default. permissions = [] class MyModelDeleteMutation(ModelDeleteMutation): class Meta: model = MyModel object_permissions = [ 'can_write', ] class MyModelCreateMutation(ModelCreateMutation): class Meta: model = MyModel @classmethod def after_save(cls, info, instance, cleaned_input=None): # If the user created the object, allow him to modify it assign_perm('can_write', info.context.user, instance) class Mutation(graphene.ObjectType): my_model_create = MyModelCreateMutation.Field() my_model_update = MyModelUpdateMutation.Field() my_model_delete = MyModelDeleteMutation.Field() ``` This can be used to create/update/delete like: ```graphql # Create mutation mutation { myModelCreate(input: { name: "foobar" }) { myModel { name } errors { field message } } } # Update mutation mutation { myModelUpdate(input: { id: "", name: "foobar" }) { myModel { name } errors { field message } } } # Delete mutation mutation { myModelDelete(input: { id: "" }) { myModel { name } errors { field message } } } ``` Any validation errors will be presented in the `errors` return value. To turn off auto related relations addition to the mutation input - set global `MUTATIONS_INCLUDE_REVERSE_RELATIONS` parameter to `False` in your `settings.py`: ``` GRAPHENE_DJANGO_PLUS = { 'MUTATIONS_INCLUDE_REVERSE_RELATIONS': False } ``` Note: in case reverse relation does not have `related_name` attribute set - mutation input will be generated as Django itself is generating by appending `_set` to the lower cased model name - `modelname_set` ## License This project is licensed under MIT licence (see `LICENSE` for more info) ## Contributing Make sure to have [poetry](https://python-poetry.org/) installed. Install dependencies with: ```bash poetry install ``` Run the testsuite with: ```bash poetry run pytest ``` Feel free to fork the project and send me pull requests with new features, corrections and translations. We'll gladly merge them and release new versions ASAP. %package -n python3-graphene-django-plus Summary: Tools to easily create permissioned CRUD endpoints in graphene. Provides: python-graphene-django-plus BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-pip %description -n python3-graphene-django-plus # graphene-django-plus [![build status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2F0soft%2Fgraphene-django-plus%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/0soft/graphene-django-plus/goto?ref=master) [![docs status](https://img.shields.io/readthedocs/graphene-django-plus.svg)](https://graphene-django-plus.readthedocs.io) [![coverage](https://img.shields.io/codecov/c/github/0soft/graphene-django-plus.svg)](https://codecov.io/gh/0soft/graphene-django-plus) [![PyPI version](https://img.shields.io/pypi/v/graphene-django-plus.svg)](https://pypi.org/project/graphene-django-plus/) ![python version](https://img.shields.io/pypi/pyversions/graphene-django-plus.svg) ![django version](https://img.shields.io/pypi/djversions/graphene-django-plus.svg) > ## DEPRECATION WARNING > > Graphene itself is abandoned and most users are migrating to other better alternatives, like > [strawberry](https://github.com/strawberry-graphql/strawberry). > > For that reason this lib is being deprecated and new features will no longer be developed for it. > Maintenance is still going to happen and PRs are still welcomed though. > > For anyone looking for alternatives, I created > [strawberry-django-plus](https://github.com/blb-ventures/strawberry-django-plus) to use not > only as a migration path to the projects I maintain, but also to add even more awesome features. > Be sure to check it out! Tools to easily create permissioned CRUD endpoints in [graphene-django](https://github.com/graphql-python/graphene-django). ## Install ```bash pip install graphene-django-plus ``` To make use of everything this lib has to offer, it is recommended to install both [graphene-django-optimizer](https://github.com/tfoxy/graphene-django-optimizer) and [django-guardian](https://github.com/django-guardian/django-guardian). ```bash pip install graphene-django-optimizer django-guardian ``` ## What it does - Provides some base types for Django Models to improve querying them with: - Unauthenticated user handling - Automatic optimization using [graphene-django-optimizer](https://github.com/tfoxy/graphene-django-optimizer) - Permission handling for queries using the default [django permission system](https://docs.djangoproject.com/en/2.2/topics/auth/default/#topic-authorization) - Object permission handling for queries using [django guardian](https://github.com/django-guardian/django-guardian) - Relay id conversion so querying can use the global id instead of the model's id - Provides a set of complete and simple CRUD mutations with: - Unauthenticated user handling - Permission handling using the default [django permission system](https://docs.djangoproject.com/en/2.2/topics/auth/default/#topic-authorization) - Object permission handling using [django guardian](https://github.com/django-guardian/django-guardian) - Automatic input generation based on the model (no need to write your own input type or use `django forms` and `drf serializers`) - Automatic model validation based on the model's validators - Very simple to create some quick CRUD endpoints for your models - Easy to extend and override functionalities - File upload handling ## What is included Check the [docs](https://graphene-django-plus.readthedocs.io) for a complete api documentation. ### Models - `graphene_django_plus.models.GuardedModel`: A django model that can be used either directly or as a mixin. It will provide a `.has_perm` method and a `.objects.for_user` that will be used by `ModelType` described below to check for object permissions. ### Types and Queries - `graphene_django_plus.types.ModelType`: This enchances `graphene_django_plus.DjangoModelType` by doing some automatic `prefetch` optimization on setup and also checking for objects permissions on queries when it inherits from `GuardedModel`. - `graphene_django_plus.fields.CountableConnection`: This enchances `graphene.relay.Connection` to provide a `total_count` attribute. Here is an example describing how to use those: ```py import graphene from graphene import relay from graphene_django.fields import DjangoConnectionField from graphene_django_plus.models import GuardedModel from graphene_django_plus.types import ModelType from graphene_django_plus.fields import CountableConnection class MyModel(GuardedModel): class Meta: # guardian permissions for this model permissions = [ ('can_read', "Can read the this object's info."), ] name = models.CharField(max_length=255) class MyModelType(ModelType): class Meta: model = MyModel interfaces = [relay.Node] # Use our CountableConnection connection_class = CountableConnection # When adding this to a query, only objects with a `can_read` # permission to the request's user will be allowed to return to him # Note that `can_read` was defined in the model. # If the model doesn't inherid from `GuardedModel`, `guardian` is not # installed or this list is empty, any object will be allowed. # This is empty by default object_permissions = [ 'can_read', ] # If unauthenticated users should be allowed to retrieve any object # of this type. This is not dependent on `GuardedModel` and neither # `guardian` and is defined as `False` by default public = False # A list of Django model permissions to check. Different from # object_permissions, this uses the basic Django's permission system # and thus is not dependent on `GuardedModel` and neither `guardian`. # This is an empty list by default. permissions = [] class Query(graphene.ObjectType): my_models = DjangoConnectionField(MyModelType) my_model = relay.Node.Field(MyModelType) ``` This can be queried like: ```graphql # All objects that the user has permission to see query { myModels { totalCount edges { node { id name } } } } # Single object if the user has permission to see it query { myModel(id: "") { id name } } ``` ### Mutations - `graphene_django_plus.mutations.BaseMutation`: Base mutation using `relay` and some basic permission checking. Just override its `.perform_mutation` to perform the mutation. - `graphene_django_plus.mutations.ModelMutation`: Model mutation capable of both creating and updating a model based on the existence of an `id` attribute in the input. All the model's fields will be automatically read from Django, inserted in the input type and validated. - `graphene_django_plus.mutations.ModelCreateMutation`: A `ModelMutation` enforcing a "create only" rule by excluding the `id` field from the input. - `graphene_django_plus.mutations.ModelUpdateMutation`: A `ModelMutation` enforcing a "update only" rule by making the `id` field required in the input. - `graphene_django_plus.mutations.ModelDeleteMutation`: A mutation that will receive only the model's id and will delete it (if given permission, of course). Here is an example describing how to use those: ```py import graphene from graphene import relay from graphene_django_plus.models import GuardedModel from graphene_django_plus.types import ModelType from graphene_django_plus.mutations import ( ModelCreateMutation, ModelUpdateMutation, ModelDeleteMutation, ) class MyModel(GuardedModel): class Meta: # guardian permissions for this model permissions = [ ('can_write', "Can update this object's info."), ] name = models.CharField(max_length=255) class MyModelType(ModelType): class Meta: model = MyModel interfaces = [relay.Node] class MyModelUpdateMutation(ModelUpdateMutation): class Meta: model = MyModel # Make sure only users with the given permissions can modify the # object. # If the model doesn't inherid from `GuardedModel`, `guardian` is not # installed on this list is empty, any object will be allowed. # This is empty by default. object_permissions = [ 'can_write', ] # If unauthenticated users should be allowed to retrieve any object # of this type. This is not dependent on `GuardedModel` and neither # `guardian` and is defined as `False` by default public = False # A list of Django model permissions to check. Different from # object_permissions, this uses the basic Django's permission system # and thus is not dependent on `GuardedModel` and neither `guardian`. # This is an empty list by default. permissions = [] class MyModelDeleteMutation(ModelDeleteMutation): class Meta: model = MyModel object_permissions = [ 'can_write', ] class MyModelCreateMutation(ModelCreateMutation): class Meta: model = MyModel @classmethod def after_save(cls, info, instance, cleaned_input=None): # If the user created the object, allow him to modify it assign_perm('can_write', info.context.user, instance) class Mutation(graphene.ObjectType): my_model_create = MyModelCreateMutation.Field() my_model_update = MyModelUpdateMutation.Field() my_model_delete = MyModelDeleteMutation.Field() ``` This can be used to create/update/delete like: ```graphql # Create mutation mutation { myModelCreate(input: { name: "foobar" }) { myModel { name } errors { field message } } } # Update mutation mutation { myModelUpdate(input: { id: "", name: "foobar" }) { myModel { name } errors { field message } } } # Delete mutation mutation { myModelDelete(input: { id: "" }) { myModel { name } errors { field message } } } ``` Any validation errors will be presented in the `errors` return value. To turn off auto related relations addition to the mutation input - set global `MUTATIONS_INCLUDE_REVERSE_RELATIONS` parameter to `False` in your `settings.py`: ``` GRAPHENE_DJANGO_PLUS = { 'MUTATIONS_INCLUDE_REVERSE_RELATIONS': False } ``` Note: in case reverse relation does not have `related_name` attribute set - mutation input will be generated as Django itself is generating by appending `_set` to the lower cased model name - `modelname_set` ## License This project is licensed under MIT licence (see `LICENSE` for more info) ## Contributing Make sure to have [poetry](https://python-poetry.org/) installed. Install dependencies with: ```bash poetry install ``` Run the testsuite with: ```bash poetry run pytest ``` Feel free to fork the project and send me pull requests with new features, corrections and translations. We'll gladly merge them and release new versions ASAP. %package help Summary: Development documents and examples for graphene-django-plus Provides: python3-graphene-django-plus-doc %description help # graphene-django-plus [![build status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2F0soft%2Fgraphene-django-plus%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/0soft/graphene-django-plus/goto?ref=master) [![docs status](https://img.shields.io/readthedocs/graphene-django-plus.svg)](https://graphene-django-plus.readthedocs.io) [![coverage](https://img.shields.io/codecov/c/github/0soft/graphene-django-plus.svg)](https://codecov.io/gh/0soft/graphene-django-plus) [![PyPI version](https://img.shields.io/pypi/v/graphene-django-plus.svg)](https://pypi.org/project/graphene-django-plus/) ![python version](https://img.shields.io/pypi/pyversions/graphene-django-plus.svg) ![django version](https://img.shields.io/pypi/djversions/graphene-django-plus.svg) > ## DEPRECATION WARNING > > Graphene itself is abandoned and most users are migrating to other better alternatives, like > [strawberry](https://github.com/strawberry-graphql/strawberry). > > For that reason this lib is being deprecated and new features will no longer be developed for it. > Maintenance is still going to happen and PRs are still welcomed though. > > For anyone looking for alternatives, I created > [strawberry-django-plus](https://github.com/blb-ventures/strawberry-django-plus) to use not > only as a migration path to the projects I maintain, but also to add even more awesome features. > Be sure to check it out! Tools to easily create permissioned CRUD endpoints in [graphene-django](https://github.com/graphql-python/graphene-django). ## Install ```bash pip install graphene-django-plus ``` To make use of everything this lib has to offer, it is recommended to install both [graphene-django-optimizer](https://github.com/tfoxy/graphene-django-optimizer) and [django-guardian](https://github.com/django-guardian/django-guardian). ```bash pip install graphene-django-optimizer django-guardian ``` ## What it does - Provides some base types for Django Models to improve querying them with: - Unauthenticated user handling - Automatic optimization using [graphene-django-optimizer](https://github.com/tfoxy/graphene-django-optimizer) - Permission handling for queries using the default [django permission system](https://docs.djangoproject.com/en/2.2/topics/auth/default/#topic-authorization) - Object permission handling for queries using [django guardian](https://github.com/django-guardian/django-guardian) - Relay id conversion so querying can use the global id instead of the model's id - Provides a set of complete and simple CRUD mutations with: - Unauthenticated user handling - Permission handling using the default [django permission system](https://docs.djangoproject.com/en/2.2/topics/auth/default/#topic-authorization) - Object permission handling using [django guardian](https://github.com/django-guardian/django-guardian) - Automatic input generation based on the model (no need to write your own input type or use `django forms` and `drf serializers`) - Automatic model validation based on the model's validators - Very simple to create some quick CRUD endpoints for your models - Easy to extend and override functionalities - File upload handling ## What is included Check the [docs](https://graphene-django-plus.readthedocs.io) for a complete api documentation. ### Models - `graphene_django_plus.models.GuardedModel`: A django model that can be used either directly or as a mixin. It will provide a `.has_perm` method and a `.objects.for_user` that will be used by `ModelType` described below to check for object permissions. ### Types and Queries - `graphene_django_plus.types.ModelType`: This enchances `graphene_django_plus.DjangoModelType` by doing some automatic `prefetch` optimization on setup and also checking for objects permissions on queries when it inherits from `GuardedModel`. - `graphene_django_plus.fields.CountableConnection`: This enchances `graphene.relay.Connection` to provide a `total_count` attribute. Here is an example describing how to use those: ```py import graphene from graphene import relay from graphene_django.fields import DjangoConnectionField from graphene_django_plus.models import GuardedModel from graphene_django_plus.types import ModelType from graphene_django_plus.fields import CountableConnection class MyModel(GuardedModel): class Meta: # guardian permissions for this model permissions = [ ('can_read', "Can read the this object's info."), ] name = models.CharField(max_length=255) class MyModelType(ModelType): class Meta: model = MyModel interfaces = [relay.Node] # Use our CountableConnection connection_class = CountableConnection # When adding this to a query, only objects with a `can_read` # permission to the request's user will be allowed to return to him # Note that `can_read` was defined in the model. # If the model doesn't inherid from `GuardedModel`, `guardian` is not # installed or this list is empty, any object will be allowed. # This is empty by default object_permissions = [ 'can_read', ] # If unauthenticated users should be allowed to retrieve any object # of this type. This is not dependent on `GuardedModel` and neither # `guardian` and is defined as `False` by default public = False # A list of Django model permissions to check. Different from # object_permissions, this uses the basic Django's permission system # and thus is not dependent on `GuardedModel` and neither `guardian`. # This is an empty list by default. permissions = [] class Query(graphene.ObjectType): my_models = DjangoConnectionField(MyModelType) my_model = relay.Node.Field(MyModelType) ``` This can be queried like: ```graphql # All objects that the user has permission to see query { myModels { totalCount edges { node { id name } } } } # Single object if the user has permission to see it query { myModel(id: "") { id name } } ``` ### Mutations - `graphene_django_plus.mutations.BaseMutation`: Base mutation using `relay` and some basic permission checking. Just override its `.perform_mutation` to perform the mutation. - `graphene_django_plus.mutations.ModelMutation`: Model mutation capable of both creating and updating a model based on the existence of an `id` attribute in the input. All the model's fields will be automatically read from Django, inserted in the input type and validated. - `graphene_django_plus.mutations.ModelCreateMutation`: A `ModelMutation` enforcing a "create only" rule by excluding the `id` field from the input. - `graphene_django_plus.mutations.ModelUpdateMutation`: A `ModelMutation` enforcing a "update only" rule by making the `id` field required in the input. - `graphene_django_plus.mutations.ModelDeleteMutation`: A mutation that will receive only the model's id and will delete it (if given permission, of course). Here is an example describing how to use those: ```py import graphene from graphene import relay from graphene_django_plus.models import GuardedModel from graphene_django_plus.types import ModelType from graphene_django_plus.mutations import ( ModelCreateMutation, ModelUpdateMutation, ModelDeleteMutation, ) class MyModel(GuardedModel): class Meta: # guardian permissions for this model permissions = [ ('can_write', "Can update this object's info."), ] name = models.CharField(max_length=255) class MyModelType(ModelType): class Meta: model = MyModel interfaces = [relay.Node] class MyModelUpdateMutation(ModelUpdateMutation): class Meta: model = MyModel # Make sure only users with the given permissions can modify the # object. # If the model doesn't inherid from `GuardedModel`, `guardian` is not # installed on this list is empty, any object will be allowed. # This is empty by default. object_permissions = [ 'can_write', ] # If unauthenticated users should be allowed to retrieve any object # of this type. This is not dependent on `GuardedModel` and neither # `guardian` and is defined as `False` by default public = False # A list of Django model permissions to check. Different from # object_permissions, this uses the basic Django's permission system # and thus is not dependent on `GuardedModel` and neither `guardian`. # This is an empty list by default. permissions = [] class MyModelDeleteMutation(ModelDeleteMutation): class Meta: model = MyModel object_permissions = [ 'can_write', ] class MyModelCreateMutation(ModelCreateMutation): class Meta: model = MyModel @classmethod def after_save(cls, info, instance, cleaned_input=None): # If the user created the object, allow him to modify it assign_perm('can_write', info.context.user, instance) class Mutation(graphene.ObjectType): my_model_create = MyModelCreateMutation.Field() my_model_update = MyModelUpdateMutation.Field() my_model_delete = MyModelDeleteMutation.Field() ``` This can be used to create/update/delete like: ```graphql # Create mutation mutation { myModelCreate(input: { name: "foobar" }) { myModel { name } errors { field message } } } # Update mutation mutation { myModelUpdate(input: { id: "", name: "foobar" }) { myModel { name } errors { field message } } } # Delete mutation mutation { myModelDelete(input: { id: "" }) { myModel { name } errors { field message } } } ``` Any validation errors will be presented in the `errors` return value. To turn off auto related relations addition to the mutation input - set global `MUTATIONS_INCLUDE_REVERSE_RELATIONS` parameter to `False` in your `settings.py`: ``` GRAPHENE_DJANGO_PLUS = { 'MUTATIONS_INCLUDE_REVERSE_RELATIONS': False } ``` Note: in case reverse relation does not have `related_name` attribute set - mutation input will be generated as Django itself is generating by appending `_set` to the lower cased model name - `modelname_set` ## License This project is licensed under MIT licence (see `LICENSE` for more info) ## Contributing Make sure to have [poetry](https://python-poetry.org/) installed. Install dependencies with: ```bash poetry install ``` Run the testsuite with: ```bash poetry run pytest ``` Feel free to fork the project and send me pull requests with new features, corrections and translations. We'll gladly merge them and release new versions ASAP. %prep %autosetup -n graphene-django-plus-5.0 %build %py3_build %install %py3_install install -d -m755 %{buildroot}/%{_pkgdocdir} if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi pushd %{buildroot} if [ -d usr/lib ]; then find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/lib64 ]; then find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/bin ]; then find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/sbin ]; then find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst fi touch doclist.lst if [ -d usr/share/man ]; then find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst fi popd mv %{buildroot}/filelist.lst . mv %{buildroot}/doclist.lst . %files -n python3-graphene-django-plus -f filelist.lst %dir %{python3_sitelib}/* %files help -f doclist.lst %{_docdir}/* %changelog * Fri May 05 2023 Python_Bot - 5.0-1 - Package Spec generated