Skip to content

Commit

Permalink
Added ok field and errors field to DjangoSerializerType like on Djang…
Browse files Browse the repository at this point in the history
…oSerializerMutation.

Added possibility of filtering in those queries fields that return a list of objects.
Updated DRF compatibility.
Fixed bug with filters when use global DEFAULT_PAGINATION_CLASS.
  • Loading branch information
Ernesto Perez Amigo committed Nov 14, 2017
1 parent 5920b6b commit c91f381
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 26 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,15 @@ mutation{

## 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
Expand Down
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,19 @@ You can define traditional mutations that use InputTypes or Mutations based on D
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:
*******
Expand Down
2 changes: 1 addition & 1 deletion graphene_django_extras/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .paginations import LimitOffsetGraphqlPagination, PageGraphqlPagination, CursorGraphqlPagination
from .types import DjangoObjectType, DjangoInputObjectType, DjangoListObjectType, DjangoSerializerType

VERSION = (0, 1, 1, 'final', '')
VERSION = (0, 1, 2, 'final', '')

__version__ = get_version(VERSION)

Expand Down
7 changes: 3 additions & 4 deletions graphene_django_extras/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
from graphene_django.compat import ArrayField, HStoreField, RangeField, JSONField
from graphene_django.fields import DjangoListField
from graphene_django.utils import import_single_dispatch
from rest_framework.compat import get_related_model

from .fields import DjangoFilterListField
from .utils import is_required, get_model_fields
from .utils import is_required, get_model_fields, get_related_model
from .base_types import Date, GenericForeignKeyType, GenericForeignKeyInputType

singledispatch = import_single_dispatch()
Expand Down Expand Up @@ -231,7 +230,7 @@ def dynamic_type():
if not _type:
return

if _type._meta.filter_fields and input_flag:
if _type._meta.filter_fields:
return DjangoFilterListField(_type, required=is_required(field) and input_flag == 'create')
return DjangoListField(_type, required=is_required(field) and input_flag == 'create')

Expand All @@ -252,7 +251,7 @@ def dynamic_type():
if not _type:
return

if _type._meta.filter_fields and input_flag:
if _type._meta.filter_fields:
return DjangoFilterListField(_type)
return DjangoListField(_type)

Expand Down
12 changes: 10 additions & 2 deletions graphene_django_extras/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from graphene import Field, List, ID, Argument
from graphene_django.filter.utils import get_filtering_args_from_filterset
from graphene_django.utils import maybe_queryset, is_valid_django_model, DJANGO_FILTER_INSTALLED
from graphene_django_extras.settings import graphql_api_settings

from graphene_django_extras.filters.filter import get_filterset_class
from .base_types import DjangoListObjectBase
from .paginations.pagination import BaseDjangoGraphqlPagination
from .paginations.utils import list_pagination_factory
from .utils import get_extra_filters, kwargs_formatter, queryset_factory, get_related_fields, find_field

Expand Down Expand Up @@ -101,7 +103,7 @@ def list_resolver(manager, filterset_class, filtering_args, root, info, **kwargs
except AttributeError:
qs = None

if not qs:
if qs is None:
qs = queryset_factory(manager, info.field_asts, info.fragments, **kwargs)
qs = filterset_class(data=filter_kwargs, queryset=qs).qs

Expand Down Expand Up @@ -137,7 +139,13 @@ def __init__(self, _type, pagination=None, fields=None, extra_filter_meta=None,
self.filtering_args.update({'id': Argument(ID, description='Django object unique identification field')})
kwargs['args'].update({'id': Argument(ID, description='Django object unique identification field')})

if pagination:
pagination = pagination or graphql_api_settings.DEFAULT_PAGINATION_CLASS

if pagination is not None:
assert isinstance(pagination, BaseDjangoGraphqlPagination), (
'You need to pass a valid DjangoGraphqlPagination in DjangoFilterPaginateListField, received "{}".'
).format(pagination)

pagination_kwargs = list_pagination_factory(pagination)

self.pagination = pagination
Expand Down
10 changes: 0 additions & 10 deletions graphene_django_extras/paginations/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,8 @@
# ************ PAGINATION ClASSES *************** #
# *********************************************** #
class BaseDjangoGraphqlPagination(object):
_field = None
__name__ = None

@property
def get_field(self):
return self._field

def get_pagination_field(self, type):
return GenericPaginationField(type, paginator_instance=self)

Expand All @@ -41,8 +36,6 @@ def __init__(self, default_limit=graphql_api_settings.DEFAULT_PAGE_SIZE,
max_limit=graphql_api_settings.MAX_PAGE_SIZE, limit_query_param='limit',
offset_query_param='offset'):

self._field = LimitOffsetPaginationField

# A numeric value indicating the limit to use if one is not provided by the client in a query parameter.
self.default_limit = default_limit

Expand Down Expand Up @@ -102,8 +95,6 @@ class PageGraphqlPagination(BaseDjangoGraphqlPagination):
def __init__(self, page_size=graphql_api_settings.DEFAULT_PAGE_SIZE, page_size_query_param=None,
max_page_size=graphql_api_settings.MAX_PAGE_SIZE):

self._field = PagePaginationField

# Client can control the page using this query parameter.
self.page_query_param = 'page'

Expand Down Expand Up @@ -175,7 +166,6 @@ class CursorGraphqlPagination(BaseDjangoGraphqlPagination):
page_size = graphql_api_settings.DEFAULT_PAGE_SIZE

def __init__(self, ordering='-created', cursor_query_param='cursor'):
self._field = CursorPaginationField

self.page_size_query_param = 'page_size' if not self.page_size else None
self.cursor_query_param = cursor_query_param
Expand Down
13 changes: 10 additions & 3 deletions graphene_django_extras/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from django.db.models import QuerySet
from django.utils.functional import SimpleLazyObject
from graphene import Field, InputField, ObjectType, Int, Argument, ID
from graphene import Field, InputField, ObjectType, Int, Argument, ID, Boolean, List
from graphene.types.base import BaseOptions
from graphene.types.inputobjecttype import InputObjectType, InputObjectTypeContainer
from graphene.types.utils import yank_fields_from_attrs
Expand All @@ -19,6 +19,7 @@
from .registry import get_global_registry, Registry
from .settings import graphql_api_settings
from .utils import get_Object_or_None, queryset_factory, kwargs_formatter
from .paginations.pagination import BaseDjangoGraphqlPagination

__all__ = ('DjangoObjectType', 'DjangoInputObjectType', 'DjangoListObjectType', 'DjangoSerializerType')

Expand Down Expand Up @@ -215,9 +216,12 @@ def __init_subclass_with_meta__(cls, model=None, results_field_name=None, pagina
else:
global_paginator = graphql_api_settings.DEFAULT_PAGINATION_CLASS
if global_paginator:
assert issubclass(global_paginator, BaseDjangoGraphqlPagination), (
'You need to pass a valid DjangoGraphqlPagination class in {}.Meta, received "{}".'
).format(cls.__name__, global_paginator)

global_paginator = global_paginator()
description = '{} list, paginated by {}'.format(model.__name__, global_paginator.__name__)
result_container = global_paginator.get_field(baseType, description=description)
result_container = global_paginator.get_pagination_field(baseType)
else:
result_container = DjangoListField(baseType)

Expand Down Expand Up @@ -246,6 +250,9 @@ class DjangoSerializerType(ObjectType):
DjangoSerializerType definition
"""

ok = Boolean(description='Boolean field that return mutation result request.')
errors = List(ErrorType, description='Errors list for the field')

class Meta:
abstract = True

Expand Down
16 changes: 12 additions & 4 deletions graphene_django_extras/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from django import VERSION as DJANGO_VERSION
from django.db import models
from django.apps import apps
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRel
from django.core.exceptions import ValidationError
Expand All @@ -10,9 +9,18 @@
from graphene_django.utils import is_valid_django_model, get_reverse_fields
from graphql import GraphQLList, GraphQLNonNull
from graphql.language.ast import FragmentSpread
from rest_framework.compat import _resolve_model
from six import string_types


def get_related_model(field):
# Backward compatibility patch for Django versions lower than 1.9.x
# Function taken from DRF 3.6.x
if DJANGO_VERSION < (1, 9):
return _resolve_model(field.rel.to)
return field.remote_field.model


def get_model_fields(model):

# Backward compatibility patch for Django versions lower than 1.11.x
Expand All @@ -29,7 +37,7 @@ def get_model_fields(model):
local_fields = [
(field.name, field)
for field
in all_fields_list if not isinstance(field, (ManyToOneRel, ))
in all_fields_list
]

# Make sure we don't duplicate local fields with "reverse" version
Expand Down Expand Up @@ -68,9 +76,9 @@ def create_obj(model, new_obj_key=None, *args, **kwargs):
except ValidationError as e:
raise ValidationError(e.__str__())
except TypeError as e:
raise TypeError(e.message)
raise TypeError(e.__str__())
except Exception as e:
return e.message
return e.__str__()


def get_type(_type):
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def get_packages():
license='MIT',

classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Libraries',
'Programming Language :: Python :: 2',
Expand All @@ -60,7 +59,7 @@ def get_packages():
'graphene-django>=2.0.dev2017083101',
'Django>=1.8.0',
'django-filter>=1.0.4',
'djangorestframework~=3.6.0'
'djangorestframework>=3.6.0'
],
include_package_data=True,
zip_safe=False,
Expand Down

0 comments on commit c91f381

Please sign in to comment.