Skip to content

Commit c91f381

Browse files
author
Ernesto Perez Amigo
committed
Added ok field and errors field to DjangoSerializerType like on DjangoSerializerMutation.
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.
1 parent 5920b6b commit c91f381

File tree

9 files changed

+59
-26
lines changed

9 files changed

+59
-26
lines changed

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ mutation{
284284

285285
## Change Log:
286286

287+
#### v0.1.2:
288+
1. Added ok field and errors field to DjangoSerializerType like on DjangoSerializerMutation.
289+
2. Added possibility of filtering in those queries fields that return a list of objects.
290+
3. Updated DRF compatibility.
291+
4. Fixed bug with filters when use global DEFAULT_PAGINATION_CLASS.
292+
293+
#### v0.1.1:
294+
1. Fixed error with JSONField reference on Django==1.8.x installations.
295+
287296
#### v0.1.0:
288297
1. Added DjangoSerializerType for quick Django's models types definition (See documentation).
289298
2. Moved support for Subscriptions to graphene-django-subscriptions packages for

README.rst

+13
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,19 @@ You can define traditional mutations that use InputTypes or Mutations based on D
309309
Change Log:
310310
-----------
311311

312+
*******
313+
v0.1.2:
314+
*******
315+
1. Added ok field and errors field to DjangoSerializerType like on DjangoSerializerMutation.
316+
2. Added possibility of filtering in those queries fields that return a list of objects.
317+
3. Updated DRF compatibility.
318+
4. Fixed bug with filters when use global DEFAULT_PAGINATION_CLASS.
319+
320+
*******
321+
v0.1.1:
322+
*******
323+
1. Fixed error with JSONField reference on Django==1.8.x installations.
324+
312325
*******
313326
v0.1.0:
314327
*******

graphene_django_extras/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .paginations import LimitOffsetGraphqlPagination, PageGraphqlPagination, CursorGraphqlPagination
88
from .types import DjangoObjectType, DjangoInputObjectType, DjangoListObjectType, DjangoSerializerType
99

10-
VERSION = (0, 1, 1, 'final', '')
10+
VERSION = (0, 1, 2, 'final', '')
1111

1212
__version__ = get_version(VERSION)
1313

graphene_django_extras/converter.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@
1212
from graphene_django.compat import ArrayField, HStoreField, RangeField, JSONField
1313
from graphene_django.fields import DjangoListField
1414
from graphene_django.utils import import_single_dispatch
15-
from rest_framework.compat import get_related_model
1615

1716
from .fields import DjangoFilterListField
18-
from .utils import is_required, get_model_fields
17+
from .utils import is_required, get_model_fields, get_related_model
1918
from .base_types import Date, GenericForeignKeyType, GenericForeignKeyInputType
2019

2120
singledispatch = import_single_dispatch()
@@ -231,7 +230,7 @@ def dynamic_type():
231230
if not _type:
232231
return
233232

234-
if _type._meta.filter_fields and input_flag:
233+
if _type._meta.filter_fields:
235234
return DjangoFilterListField(_type, required=is_required(field) and input_flag == 'create')
236235
return DjangoListField(_type, required=is_required(field) and input_flag == 'create')
237236

@@ -252,7 +251,7 @@ def dynamic_type():
252251
if not _type:
253252
return
254253

255-
if _type._meta.filter_fields and input_flag:
254+
if _type._meta.filter_fields:
256255
return DjangoFilterListField(_type)
257256
return DjangoListField(_type)
258257

graphene_django_extras/fields.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
from graphene import Field, List, ID, Argument
66
from graphene_django.filter.utils import get_filtering_args_from_filterset
77
from graphene_django.utils import maybe_queryset, is_valid_django_model, DJANGO_FILTER_INSTALLED
8+
from graphene_django_extras.settings import graphql_api_settings
89

910
from graphene_django_extras.filters.filter import get_filterset_class
1011
from .base_types import DjangoListObjectBase
12+
from .paginations.pagination import BaseDjangoGraphqlPagination
1113
from .paginations.utils import list_pagination_factory
1214
from .utils import get_extra_filters, kwargs_formatter, queryset_factory, get_related_fields, find_field
1315

@@ -101,7 +103,7 @@ def list_resolver(manager, filterset_class, filtering_args, root, info, **kwargs
101103
except AttributeError:
102104
qs = None
103105

104-
if not qs:
106+
if qs is None:
105107
qs = queryset_factory(manager, info.field_asts, info.fragments, **kwargs)
106108
qs = filterset_class(data=filter_kwargs, queryset=qs).qs
107109

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

140-
if pagination:
142+
pagination = pagination or graphql_api_settings.DEFAULT_PAGINATION_CLASS
143+
144+
if pagination is not None:
145+
assert isinstance(pagination, BaseDjangoGraphqlPagination), (
146+
'You need to pass a valid DjangoGraphqlPagination in DjangoFilterPaginateListField, received "{}".'
147+
).format(pagination)
148+
141149
pagination_kwargs = list_pagination_factory(pagination)
142150

143151
self.pagination = pagination

graphene_django_extras/paginations/pagination.py

-10
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,8 @@
1414
# ************ PAGINATION ClASSES *************** #
1515
# *********************************************** #
1616
class BaseDjangoGraphqlPagination(object):
17-
_field = None
1817
__name__ = None
1918

20-
@property
21-
def get_field(self):
22-
return self._field
23-
2419
def get_pagination_field(self, type):
2520
return GenericPaginationField(type, paginator_instance=self)
2621

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

44-
self._field = LimitOffsetPaginationField
45-
4639
# A numeric value indicating the limit to use if one is not provided by the client in a query parameter.
4740
self.default_limit = default_limit
4841

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

105-
self._field = PagePaginationField
106-
10798
# Client can control the page using this query parameter.
10899
self.page_query_param = 'page'
109100

@@ -175,7 +166,6 @@ class CursorGraphqlPagination(BaseDjangoGraphqlPagination):
175166
page_size = graphql_api_settings.DEFAULT_PAGE_SIZE
176167

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

180170
self.page_size_query_param = 'page_size' if not self.page_size else None
181171
self.cursor_query_param = cursor_query_param

graphene_django_extras/types.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from django.db.models import QuerySet
55
from django.utils.functional import SimpleLazyObject
6-
from graphene import Field, InputField, ObjectType, Int, Argument, ID
6+
from graphene import Field, InputField, ObjectType, Int, Argument, ID, Boolean, List
77
from graphene.types.base import BaseOptions
88
from graphene.types.inputobjecttype import InputObjectType, InputObjectTypeContainer
99
from graphene.types.utils import yank_fields_from_attrs
@@ -19,6 +19,7 @@
1919
from .registry import get_global_registry, Registry
2020
from .settings import graphql_api_settings
2121
from .utils import get_Object_or_None, queryset_factory, kwargs_formatter
22+
from .paginations.pagination import BaseDjangoGraphqlPagination
2223

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

@@ -215,9 +216,12 @@ def __init_subclass_with_meta__(cls, model=None, results_field_name=None, pagina
215216
else:
216217
global_paginator = graphql_api_settings.DEFAULT_PAGINATION_CLASS
217218
if global_paginator:
219+
assert issubclass(global_paginator, BaseDjangoGraphqlPagination), (
220+
'You need to pass a valid DjangoGraphqlPagination class in {}.Meta, received "{}".'
221+
).format(cls.__name__, global_paginator)
222+
218223
global_paginator = global_paginator()
219-
description = '{} list, paginated by {}'.format(model.__name__, global_paginator.__name__)
220-
result_container = global_paginator.get_field(baseType, description=description)
224+
result_container = global_paginator.get_pagination_field(baseType)
221225
else:
222226
result_container = DjangoListField(baseType)
223227

@@ -246,6 +250,9 @@ class DjangoSerializerType(ObjectType):
246250
DjangoSerializerType definition
247251
"""
248252

253+
ok = Boolean(description='Boolean field that return mutation result request.')
254+
errors = List(ErrorType, description='Errors list for the field')
255+
249256
class Meta:
250257
abstract = True
251258

graphene_django_extras/utils.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# -*- coding: utf-8 -*-
22
from django import VERSION as DJANGO_VERSION
3-
from django.db import models
43
from django.apps import apps
54
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRel
65
from django.core.exceptions import ValidationError
@@ -10,9 +9,18 @@
109
from graphene_django.utils import is_valid_django_model, get_reverse_fields
1110
from graphql import GraphQLList, GraphQLNonNull
1211
from graphql.language.ast import FragmentSpread
12+
from rest_framework.compat import _resolve_model
1313
from six import string_types
1414

1515

16+
def get_related_model(field):
17+
# Backward compatibility patch for Django versions lower than 1.9.x
18+
# Function taken from DRF 3.6.x
19+
if DJANGO_VERSION < (1, 9):
20+
return _resolve_model(field.rel.to)
21+
return field.remote_field.model
22+
23+
1624
def get_model_fields(model):
1725

1826
# Backward compatibility patch for Django versions lower than 1.11.x
@@ -29,7 +37,7 @@ def get_model_fields(model):
2937
local_fields = [
3038
(field.name, field)
3139
for field
32-
in all_fields_list if not isinstance(field, (ManyToOneRel, ))
40+
in all_fields_list
3341
]
3442

3543
# Make sure we don't duplicate local fields with "reverse" version
@@ -68,9 +76,9 @@ def create_obj(model, new_obj_key=None, *args, **kwargs):
6876
except ValidationError as e:
6977
raise ValidationError(e.__str__())
7078
except TypeError as e:
71-
raise TypeError(e.message)
79+
raise TypeError(e.__str__())
7280
except Exception as e:
73-
return e.message
81+
return e.__str__()
7482

7583

7684
def get_type(_type):

setup.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ def get_packages():
3737
license='MIT',
3838

3939
classifiers=[
40-
'Development Status :: 3 - Alpha',
4140
'Intended Audience :: Developers',
4241
'Topic :: Software Development :: Libraries',
4342
'Programming Language :: Python :: 2',
@@ -60,7 +59,7 @@ def get_packages():
6059
'graphene-django>=2.0.dev2017083101',
6160
'Django>=1.8.0',
6261
'django-filter>=1.0.4',
63-
'djangorestframework~=3.6.0'
62+
'djangorestframework>=3.6.0'
6463
],
6564
include_package_data=True,
6665
zip_safe=False,

0 commit comments

Comments
 (0)