skip to navigation
skip to content

graphene-django-extras 0.1.2

Graphene-Django-Extras add some extra funcionalities to graphene-django to facilitate the graphql use without Relay and allow paginations and filtering integration

Latest Version: 0.1.3a1

This package add some extra functionalities to graphene-django to facilitate the graphql use without Relay:
  1. Allows pagination and filtering on Queries.
  2. Allows to define DjangoRestFramework serializers based Mutations.

NOTE: Subscription support was moved to graphene-django-subscriptions due incompatibility with subscriptions on graphene-django>=2.0

Installation:

For installing graphene-django-extras, just run this command in your shell:

pip install "graphene-django-extras"

Documentation:

Extra functionalities:

Fields:
  1. DjangoObjectField
  2. DjangoFilterListField
  3. DjangoFilterPaginateListField
  4. DjangoListObjectField (Recommended for Queries definition)
Mutations:
  1. DjangoSerializerMutation (Recommended for Mutations definition)
Types:
  1. DjangoListObjectType (Recommended for Types definition)
  2. DjangoInputObjectType
  3. DjangoSerializerType (Recommended for quick queries and mutations definitions)
Paginations:
  1. LimitOffsetGraphqlPagination
  2. PageGraphqlPagination
  3. CursorGraphqlPagination (coming soon)

Queries and Mutations examples:

This is a basic example of graphene-django-extras package use. You can configure global params for DjangoListObjectType classes pagination definitions on settings.py like this:

GRAPHENE_DJANGO_EXTRAS = {
    'DEFAULT_PAGINATION_CLASS': 'graphene_django_extras.paginations.LimitOffsetGraphqlPagination',
    'DEFAULT_PAGE_SIZE': 20,
    'MAX_PAGE_SIZE': 50,
}

1- Types Definition:

from django.contrib.auth.models import User
from graphene_django import DjangoObjectType
from graphene_django_extras import DjangoListObjectType, DjangoSerializerType
from graphene_django_extras.pagination import LimitOffsetGraphqlPagination

from .serializers import UserSerializer


class UserType(DjangoObjectType):
    class Meta:
        model = User
        description = " Type definition for a single user object "
        filter_fields = {
            'id': ['exact', ],
            'first_name': ['icontains', 'iexact'],
            'last_name': ['icontains', 'iexact'],
            'username': ['icontains', 'iexact'],
            'email': ['icontains', 'iexact']
        }


class UserListType(DjangoListObjectType):
    class Meta:
        description = " Type definition for users objects list "
        model = User
        pagination = LimitOffsetGraphqlPagination()


class UserModelType(DjangoSerializerType):
    """ With this type definition it't necessary a mutation definition for models """

    class Meta:
        description = " User's model type definition "
        serializer_class = UserSerializer
        pagination = LimitOffsetGraphqlPagination(default_limit=25)
        filter_fields = {
            'id': ['exact', ],
            'first_name': ['icontains', 'iexact'],
            'last_name': ['icontains', 'iexact'],
            'username': ['icontains', 'iexact'],
            'email': ['icontains', 'iexact'],
            'is_staff': ['exact']
        }

2- You can to define InputTypes for use on mutations:

from graphene_django_extras import DjangoInputObjectType


class UserInput(DjangoInputObjectType):
    class Meta:
        description = " User InputType definition to use as input on an Arguments class on traditional Mutations "
        model = User

3- Defining Mutations:

You can define traditional mutations that use InputTypes or Mutations based on DRF serializers:

import graphene
from .serializers import UserSerializer
from graphene_django_extras import DjangoSerializerMutation
from .types import UserType
from .input_types import UserInputType


class UserSerializerMutation(DjangoSerializerMutation):
    """
        DjangoSerializerMutation auto implement Create, Delete and Update functions
    """
    class Meta:
        description = " DRF serializer based Mutation for Users "
        serializer_class = UserSerializer


class UserMutation(graphene.Mutation):
    """
        On traditional mutation classes definition you must implement the mutate function
    """

    user = graphene.Field(UserType, required=False)

    class Arguments:
        new_user = graphene.Argument(UserInput)

    class Meta:
        description = " Graphene traditional mutation for Users "

    @classmethod
    def mutate(cls, root, info, *args, **kwargs):
        ...

4- Defining schemes:

import graphene
from graphene_django_extras import DjangoObjectField, DjangoListObjectField, DjangoFilterPaginateListField, DjangoFilterListField, LimitOffsetGraphqlPagination
from .types import UserType, UserListType, UserModelType
from .mutations import UserMutation, UserSerializerMutation


class Queries(graphene.ObjectType):
    # Possible User list queries definitions
    all_users = DjangoListObjectField(UserListType, description=_('All Users query'))
    all_users1 = DjangoFilterPaginateListField(UserType, pagination=LimitOffsetGraphqlPagination())
    all_users2 = DjangoFilterListField(UserType)
    all_users3 = DjangoListObjectField(UserListType, filterset_class=UserFilter, description=_('All Users query'))

    # Defining a query for a single user
    # The DjangoObjectField have a ID type input field, that allow filter by id and is't necessary to define resolve function
    user = DjangoObjectField(UserType, description=_('Single User query'))

    # Another way to define a query to single user
    user1 = DjangoObjectField(UserListType.getOne(), description=_('User List with pagination and filtering'))

    # Exist two ways to define single or list user queries with DjangoSerializerType
    user_retrieve1, user_list1 = UserModelType.QueryFields(description='Some description message for both queries',
                                                           deprecation_reason='Some deprecation message for both queries')
    user_retrieve2 = UserModelType.RetrieveField(description='Some description message for retrieve query',
                                                 deprecation_reason='Some deprecation message for retrieve query')
    user_list2 = UserModelType.ListField(description='Some description message for list query',
                                         deprecation_reason='Some deprecation message for list query')


class Mutations(graphene.ObjectType):
    user_create = UserSerializerMutation.CreateField(deprecation_reason='Some one deprecation message')
    user_delete = UserSerializerMutation.DeleteField()
    user_update = UserSerializerMutation.UpdateField()

    # Exist two ways to define mutations with DjangoSerializerType
    user_create1, user_delete1, user_update1 = UserModelType.MutationFields(
        description='Some description message for create, delete and update mutations',
        deprecation_reason='Some deprecation message for create, delete and update mutations')

    user_create2 = UserModelType.CreateField(description='Description message for create')
    user_delete2 = UserModelType.DeleteField(description='Description message for delete')
    user_update2 = UserModelType.UpdateField(description='Description message for update')

    traditional_user_mutation = UserMutation.Field()

5- Queries’s examples:

{
    allUsers(username_Icontains:"john"){
        results(limit:5, offset:5){
            id
            username
            firstName
            lastName
        }
        totalCount
    }

    allUsers1(lastName_Iexact:"Doe", limit:5, offset:0){
        id
        username
        firstName
        lastName
    }

    allUsers2(firstName_Icontains: "J"){
        id
        username
        firstName
        lastName
    }

    user(id:2){
        id
        username
        firstName
    }

    user1(id:2){
        id
        username
        firstName
    }
}

6- Mutations’s examples:

mutation{
    userCreate(newUser:{password:"test*123", email: "test@test.com", username:"test"}){
        user{
            id
            username
            firstName
            lastName
        }
        ok
        errors{
            field
            messages
        }
    }

    userDelete(id:1){
        ok
        errors{
            field
            messages
        }
    }

    userUpdate(newUser:{id:1, username:"John"}){
        user{
            id
            username
        }
        ok
        errors{
            field
            messages
        }
    }
}

Change Log:

v0.1.2:

  1. Added ok field and errors field to DjangoSerializerType like on DjangoSerializerMutation.
  2. Added possibility of filtering in those queries fields that return a list of objects.
  3. Updated DRF compatibility.
  4. Fixed bug with filters when use global DEFAULT_PAGINATION_CLASS.

v0.1.1:

  1. Fixed error with JSONField reference on Django==1.8.x installations.

v0.1.0:

  1. Added DjangoSerializerType for quick Django’s models types definition (See documentation).
  2. Moved support for Subscriptions to graphene-django-subscriptions packages for incompatibility with graphene-django>=2.0.
  3. Fixed bug on DjangoFilterPaginateListField’s pagination.

v0.1.0-alpha12:

  1. Added new settings param: MAX_PAGE_SIZE, to use on GRAPHENE_DJANGO_EXTRAS configuration dict for better customize DjangoListObjectType’s pagination.
  2. Added support to Django’s field: GenericRel.
  3. Improve model’s fields calculation for to add all possible related and reverse fields.
  4. Improved documentation translation.

v0.1.0-alpha11:

  1. Improved ordering for showed fields on graphqli’s IDE.
  2. Added better descriptions for auto generated fields.

v0.1.0-alpha10:

  1. Improve converter.py file to avoid create field for auto generate OneToOneField product of an inheritance.
  2. Fixed bug in Emun generation for fields with choices of model inheritance child.

v0.1.0-alpha9:

  1. Fixed bug on GenericType and GenericInputType generations for Queries list Type and Mutations.

v0.1.0-alpha6:

  1. Fixed with exclude fields and converter function.

v0.1.0-alpha5:

  1. Updated to graphene-django>=2.0.
  2. Fixed minor bugs on queryset_builder performance.

v0.1.0-alpha4:

  1. Add queryset options to DjangoListObjectType Meta class for specify wanted model queryset.
  2. Add AuthenticatedGraphQLView on graphene_django_extras.views for use ‘permission’, ‘authorization’ and ‘throttle’ classes based on the DRF settings. Special thanks to @jacobh for this comment.

v0.1.0-alpha3:

  1. Fixed bug on subscriptions when not specified any field in “data” parameter to bean return on notification message.

v0.1.0-alpha2:

  1. Fixed bug when subscribing to a given action (create, update pr delete).
  2. Added intuitive and simple web tool to test notifications of graphene-django-extras subscription.

v0.1.0-alpha1:

  1. Added support to multiselect choices values for models.CharField with choices attribute, on queries and mutations. Example: Integration with django-multiselectfield package.
  2. Added support to GenericForeignKey and GenericRelation fields, on queries and mutations.
  3. Added first approach to support Subscriptions with Channels, with subscribe and unsubscribe operations. Using channels-api package.
  4. Fixed minors bugs.

v0.0.4:

  1. Fix error on DateType encode.

v0.0.3:

  1. Implement custom implementation of DateType for use converter and avoid error on Serializer Mutation.

v0.0.2:

  1. Changed dependency of DRF to 3.6.4 on setup.py file, to avoid an import error produced by some changes in new version of DRF=3.7.0 and because DRF 3.7.0 dropped support to Django versions < 1.10.

v0.0.1:

  1. Fixed bug on DjangoInputObjectType class that refer to unused interface attribute.
  2. Added support to create nested objects like in DRF <http://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations>, it’s valid to SerializerMutation and DjangoInputObjectType, only is necessary to specify nested_fields=True on its Meta class definition.
  3. Added support to show, only in mutations types to create objects and with debug=True on settings, inputs autocomplete ordered by required fields first.
  4. Fixed others minors bugs.

v0.0.1-rc.2:

  1. Make queries pagination configuration is more friendly.

v0.0.1-rc.1:

  1. Fixed a bug with input fields in the converter function.

v0.0.1-beta.10:

  1. Fixed bug in the queryset_factory function because it did not always return a queryset.

v0.0.1-beta.9:

  1. Remove hard dependence with psycopg2 module.
  2. Fixed bug that prevented use queries with fragments.
  3. Fixed bug relating to custom django_filters module and ordering fields.

v0.0.1-beta.6:

  1. Optimizing imports, fix some minors bugs and working on performance.

v0.0.1-beta.5:

  1. Repair conflict on converter.py, by the use of get_related_model function with: OneToOneRel, ManyToManyRel and ManyToOneRel.

v0.0.1-beta.4:

  1. First commit
 
File Type Py Version Uploaded on Size
graphene_django_extras-0.1.2-py2.py3-none-any.whl (md5) Python Wheel py2.py3 2017-11-14 34KB
graphene_django_extras-0.1.2.tar.gz (md5) Source 2017-11-14 26KB