Skip to content

Commit b8fb64d

Browse files
authored
Merge branch 'master' into fix-select-related
2 parents 1d76db8 + dfa0a06 commit b8fb64d

File tree

11 files changed

+202
-35
lines changed

11 files changed

+202
-35
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ A [Django](https://www.djangoproject.com/) integration for [Graphene](http://gra
1212
For instaling graphene, just run this command in your shell
1313

1414
```bash
15-
pip install "graphene-django>=2.0.dev"
15+
pip install "graphene-django>=2.0"
1616
```
1717

1818
### Settings
@@ -67,7 +67,6 @@ class User(DjangoObjectType):
6767
class Query(graphene.ObjectType):
6868
users = graphene.List(User)
6969

70-
@graphene.resolve_only_args
7170
def resolve_users(self):
7271
return UserModel.objects.all()
7372

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ For instaling graphene, just run this command in your shell
1717

1818
.. code:: bash
1919
20-
pip install "graphene-django>=2.0.dev"
20+
pip install "graphene-django>=2.0"
2121
2222
Settings
2323
~~~~~~~~

docs/authorization.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ This is easy, simply use the ``only_fields`` meta attribute.
3434
only_fields = ('title', 'content')
3535
interfaces = (relay.Node, )
3636
37-
conversely you can use ``exclude_fields`` meta atrribute.
37+
conversely you can use ``exclude_fields`` meta attribute.
3838

3939
.. code:: python
4040

docs/tutorial-plain.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,8 @@ We can update our schema to support that, by adding new query for ``ingredient``
445445
return Ingredient.objects.all()
446446
447447
def resolve_category(self, info, **kwargs):
448-
id = kargs.get('id')
449-
name = kargs.get('name')
448+
id = kwargs.get('id')
449+
name = kwargs.get('name')
450450
451451
if id is not None:
452452
return Category.objects.get(pk=id)
@@ -457,8 +457,8 @@ We can update our schema to support that, by adding new query for ``ingredient``
457457
return None
458458
459459
def resolve_ingredient(self, info, **kwargs):
460-
id = kargs.get('id')
461-
name = kargs.get('name')
460+
id = kwargs.get('id')
461+
name = kwargs.get('name')
462462
463463
if id is not None:
464464
return Ingredient.objects.get(pk=id)

graphene_django/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
DjangoConnectionField,
66
)
77

8-
__version__ = '2.0.dev2017083101'
8+
__version__ = '2.0.0'
99

1010
__all__ = [
1111
'__version__',

graphene_django/filter/fields.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@ def merge_querysets(cls, default_queryset, queryset):
6161
low = default_queryset.query.low_mark or queryset.query.low_mark
6262
high = default_queryset.query.high_mark or queryset.query.high_mark
6363
default_queryset.query.clear_limits()
64-
6564
queryset = super(cls, cls).merge_querysets(default_queryset, queryset)
66-
6765
queryset.query.set_limits(low, high)
6866
return queryset
6967

graphene_django/filter/tests/test_fields.py

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
import pytest
44

5-
from graphene import Field, ObjectType, Schema, Argument, Float
5+
from graphene import Field, ObjectType, Schema, Argument, Float, Boolean, String
66
from graphene.relay import Node
77
from graphene_django import DjangoObjectType
88
from graphene_django.forms import (GlobalIDFormField,
99
GlobalIDMultipleChoiceField)
1010
from graphene_django.tests.models import Article, Pet, Reporter
1111
from graphene_django.utils import DJANGO_FILTER_INSTALLED
1212

13+
# for annotation test
14+
from django.db.models import TextField, Value
15+
from django.db.models.functions import Concat
16+
1317
pytestmark = []
1418

1519
if DJANGO_FILTER_INSTALLED:
@@ -534,3 +538,135 @@ def resolve_all_reporters(self, info, **args):
534538
assert str(result.errors[0]) == (
535539
'Received two sliced querysets (high mark) in the connection, please slice only in one.'
536540
)
541+
542+
def test_order_by_is_perserved():
543+
class ReporterType(DjangoObjectType):
544+
class Meta:
545+
model = Reporter
546+
interfaces = (Node, )
547+
filter_fields = ()
548+
549+
class Query(ObjectType):
550+
all_reporters = DjangoFilterConnectionField(ReporterType, reverse_order=Boolean())
551+
552+
def resolve_all_reporters(self, info, reverse_order=False, **args):
553+
reporters = Reporter.objects.order_by('first_name')
554+
555+
if reverse_order:
556+
return reporters.reverse()
557+
558+
return reporters
559+
560+
Reporter.objects.create(
561+
first_name='b',
562+
)
563+
r = Reporter.objects.create(
564+
first_name='a',
565+
)
566+
567+
schema = Schema(query=Query)
568+
query = '''
569+
query NodeFilteringQuery {
570+
allReporters(first: 1) {
571+
edges {
572+
node {
573+
firstName
574+
}
575+
}
576+
}
577+
}
578+
'''
579+
expected = {
580+
'allReporters': {
581+
'edges': [{
582+
'node': {
583+
'firstName': 'a',
584+
}
585+
}]
586+
}
587+
}
588+
589+
result = schema.execute(query)
590+
assert not result.errors
591+
assert result.data == expected
592+
593+
594+
reverse_query = '''
595+
query NodeFilteringQuery {
596+
allReporters(first: 1, reverseOrder: true) {
597+
edges {
598+
node {
599+
firstName
600+
}
601+
}
602+
}
603+
}
604+
'''
605+
606+
reverse_expected = {
607+
'allReporters': {
608+
'edges': [{
609+
'node': {
610+
'firstName': 'b',
611+
}
612+
}]
613+
}
614+
}
615+
616+
reverse_result = schema.execute(reverse_query)
617+
618+
assert not reverse_result.errors
619+
assert reverse_result.data == reverse_expected
620+
621+
def test_annotation_is_perserved():
622+
class ReporterType(DjangoObjectType):
623+
full_name = String()
624+
625+
def resolve_full_name(instance, info, **args):
626+
return instance.full_name
627+
628+
class Meta:
629+
model = Reporter
630+
interfaces = (Node, )
631+
filter_fields = ()
632+
633+
class Query(ObjectType):
634+
all_reporters = DjangoFilterConnectionField(ReporterType)
635+
636+
def resolve_all_reporters(self, info, **args):
637+
return Reporter.objects.annotate(
638+
full_name=Concat('first_name', Value(' '), 'last_name', output_field=TextField())
639+
)
640+
641+
Reporter.objects.create(
642+
first_name='John',
643+
last_name='Doe',
644+
)
645+
646+
schema = Schema(query=Query)
647+
648+
query = '''
649+
query NodeFilteringQuery {
650+
allReporters(first: 1) {
651+
edges {
652+
node {
653+
fullName
654+
}
655+
}
656+
}
657+
}
658+
'''
659+
expected = {
660+
'allReporters': {
661+
'edges': [{
662+
'node': {
663+
'fullName': 'John Doe',
664+
}
665+
}]
666+
}
667+
}
668+
669+
result = schema.execute(query)
670+
671+
assert not result.errors
672+
assert result.data == expected

graphene_django/tests/test_types.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from mock import patch
22

3-
from graphene import Interface, ObjectType, Schema
3+
from graphene import Interface, ObjectType, Schema, Connection, String
44
from graphene.relay import Node
55

66
from .. import registry
@@ -17,11 +17,23 @@ class Meta:
1717
model = ReporterModel
1818

1919

20+
class ArticleConnection(Connection):
21+
'''Article Connection'''
22+
test = String()
23+
24+
def resolve_test():
25+
return 'test'
26+
27+
class Meta:
28+
abstract = True
29+
30+
2031
class Article(DjangoObjectType):
2132
'''Article description'''
2233
class Meta:
2334
model = ArticleModel
2435
interfaces = (Node, )
36+
connection_class = ArticleConnection
2537

2638

2739
class RootQuery(ObjectType):
@@ -74,6 +86,7 @@ def test_schema_representation():
7486
type ArticleConnection {
7587
pageInfo: PageInfo!
7688
edges: [ArticleEdge]!
89+
test: String
7790
}
7891
7992
type ArticleEdge {

graphene_django/types.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class DjangoObjectType(ObjectType):
4545
@classmethod
4646
def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=False,
4747
only_fields=(), exclude_fields=(), filter_fields=None, connection=None,
48-
use_connection=None, interfaces=(), **options):
48+
connection_class=None, use_connection=None, interfaces=(), **options):
4949
assert is_valid_django_model(model), (
5050
'You need to pass a valid Django Model in {}.Meta, received "{}".'
5151
).format(cls.__name__, model)
@@ -71,7 +71,11 @@ def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=Fa
7171

7272
if use_connection and not connection:
7373
# We create the connection automatically
74-
connection = Connection.create_type('{}Connection'.format(cls.__name__), node=cls)
74+
if not connection_class:
75+
connection_class = Connection
76+
77+
connection = connection_class.create_type(
78+
'{}Connection'.format(cls.__name__), node=cls)
7579

7680
if connection is not None:
7781
assert issubclass(connection, Connection), (

0 commit comments

Comments
 (0)