Skip to content

Commit 0a5020b

Browse files
zbyte64jkimbo
authored andcommitted
Get queryset (#528)
* first attempt at adding get_queryset * add queryset_resolver to DjangoConnectionField and fix test failures * cleanup get_queryset API to match proposal as close as possible * pep8 fix: W293 * document get_queryset usage * add test for when get_queryset is defined on DjangoObjectType
1 parent fcc3de2 commit 0a5020b

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

docs/authorization.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,29 @@ schema is simple.
9696
9797
result = schema.execute(query, context_value=request)
9898
99+
100+
Global Filtering
101+
----------------
102+
103+
If you are using ``DjangoObjectType`` you can define a custom `get_queryset`.
104+
105+
.. code:: python
106+
107+
from graphene import relay
108+
from graphene_django.types import DjangoObjectType
109+
from .models import Post
110+
111+
class PostNode(DjangoObjectType):
112+
class Meta:
113+
model = Post
114+
115+
@classmethod
116+
def get_queryset(cls, queryset, info):
117+
if info.context.user.is_anonymous:
118+
return queryset.filter(published=True)
119+
return queryset
120+
121+
99122
Filtering ID-based Node Access
100123
------------------------------
101124

graphene_django/fields.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def get_manager(self):
6767
else:
6868
return self.model._default_manager
6969

70+
@classmethod
71+
def resolve_queryset(cls, connection, queryset, info, args):
72+
return connection._meta.node.get_queryset(queryset, info)
73+
7074
@classmethod
7175
def merge_querysets(cls, default_queryset, queryset):
7276
if default_queryset.query.distinct and not queryset.query.distinct:
@@ -135,7 +139,8 @@ def connection_resolver(
135139
args["last"] = min(last, max_limit)
136140

137141
iterable = resolver(root, info, **args)
138-
on_resolve = partial(cls.resolve_connection, connection, default_manager, args)
142+
queryset = cls.resolve_queryset(connection, default_manager, info, args)
143+
on_resolve = partial(cls.resolve_connection, connection, queryset, args)
139144

140145
if Promise.is_thenable(iterable):
141146
return Promise.resolve(iterable).then(on_resolve)

graphene_django/tests/test_query.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,3 +1007,47 @@ class Query(graphene.ObjectType):
10071007

10081008
result = schema.execute(query)
10091009
assert result.errors
1010+
1011+
1012+
def test_should_resolve_get_queryset_connectionfields():
1013+
reporter_1 = Reporter.objects.create(
1014+
first_name="John", last_name="Doe", email="johndoe@example.com", a_choice=1
1015+
)
1016+
reporter_2 = CNNReporter.objects.create(
1017+
first_name="Some",
1018+
last_name="Guy",
1019+
email="someguy@cnn.com",
1020+
a_choice=1,
1021+
reporter_type=2, # set this guy to be CNN
1022+
)
1023+
1024+
class ReporterType(DjangoObjectType):
1025+
class Meta:
1026+
model = Reporter
1027+
interfaces = (Node,)
1028+
1029+
@classmethod
1030+
def get_queryset(cls, queryset, info):
1031+
return queryset.filter(reporter_type=2)
1032+
1033+
class Query(graphene.ObjectType):
1034+
all_reporters = DjangoConnectionField(ReporterType)
1035+
1036+
schema = graphene.Schema(query=Query)
1037+
query = """
1038+
query ReporterPromiseConnectionQuery {
1039+
allReporters(first: 1) {
1040+
edges {
1041+
node {
1042+
id
1043+
}
1044+
}
1045+
}
1046+
}
1047+
"""
1048+
1049+
expected = {"allReporters": {"edges": [{"node": {"id": "UmVwb3J0ZXJUeXBlOjI="}}]}}
1050+
1051+
result = schema.execute(query)
1052+
assert not result.errors
1053+
assert result.data == expected

graphene_django/types.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,14 @@ def is_type_of(cls, root, info):
133133
model = root._meta.model._meta.concrete_model
134134
return model == cls._meta.model
135135

136+
@classmethod
137+
def get_queryset(cls, queryset, info):
138+
return queryset
139+
136140
@classmethod
137141
def get_node(cls, info, id):
142+
queryset = cls.get_queryset(cls._meta.model.objects, info)
138143
try:
139-
return cls._meta.model.objects.get(pk=id)
144+
return queryset.get(pk=id)
140145
except cls._meta.model.DoesNotExist:
141146
return None

0 commit comments

Comments
 (0)