`order_by` clause issue with django & graphql
See original GitHub issueHi,
When using the order_by
clause in graphql,
- the graphql representation is correctly
orderBy
(camelCase). - the value however is expected in snake case, which does not match the graphql auto generated code (it should match the API exposed field in all logic).
I tried to fix this but there are 2 places I could find where the order by is injected in a djgango qs:
- In
graphene.contrib.django.filter.fields.DjangoFilterConnectionField
def get_order(self, args):
return args.get('order_by', None)
Which does not tackle the snake case at all but at least the return is correctly handled by (in case of None
(same file):
def get_queryset(self, qs, args, info):
filterset_class = self.filterset_class
filter_kwargs = self.get_filter_kwargs(args)
order = self.get_order(args)
if order:
qs = qs.order_by(order)
unknown = filterset_class(data=filter_kwargs, queryset=qs)
return unknown
This in also (not sure why, maybe I did something wrong) pushed to:
django_filters.filterset.BaseFilterSet
@property
def qs(self):
if not hasattr(self, '_qs'):
valid = self.is_bound and self.form.is_valid()
if self.strict and self.is_bound and not valid:
self._qs = self.queryset.none()
return self._qs
# start with all the results and filter from there
qs = self.queryset.all()
for name, filter_ in six.iteritems(self.filters):
value = None
if valid:
value = self.form.cleaned_data[name]
else:
raw_value = self.form[name].value()
try:
value = self.form.fields[name].clean(raw_value)
except forms.ValidationError:
# for invalid values either:
# strictly "apply" filter yielding no results and get outta here
if self.strict:
self._qs = self.queryset.none()
return self._qs
else: # or ignore this filter altogether
pass
if value is not None: # valid & clean data
qs = filter_.filter(qs, value)
if self._meta.order_by:
order_field = self.form.fields[self.order_by_field]
data = self.form[self.order_by_field].data
ordered_value = None
try:
ordered_value = order_field.clean(data)
except forms.ValidationError:
pass
if ordered_value in EMPTY_VALUES and self.strict:
ordered_value = self.form.fields[self.order_by_field].choices[0][0]
if ordered_value:
qs = qs.order_by(*self.get_order_by(ordered_value))
self._qs = qs
return self._qs
Which does not handle at all the None
return for get_order_by
.
- When I tested this, I got it not to crash turning the camelCase to snake case in the
get_order
method, however after that, while the qs was correct (I printed it out) the return from the API was systematically empty… (in that case #2 did not seem to kick in) - When I tested sorting by a composite field (field that I had defined on the
Node
manually and not part of the django model) is when I hit #1 and #2 here. I could not get this working at all. - When the system finds an
order_by
it does not know: it prints the django error which exposes all the fields of the raw django model to the API: not super secure… It seems like the system does not validate theorder_by
“clause” / arguments before sending it to django.
This is what I found after a couple days of debugging and trying to go around the issue. Please let me know if I can help in any way. The doc was very light on the subject and I understand from slack that @syrusakbary has code changes.
I did not know the best way to help you/us resolve this. Thank you.
Issue Analytics
- State:
- Created 7 years ago
- Comments:15 (4 by maintainers)
Top Results From Across the Web
Add ordering to your Django-Graphene GraphQL API
If the GraphQL query is sent without the orderBy argument then we never enter the if order block and instantly return the queryset...
Read more >Django Graphene Relay order_by (OrderingFilter)
Eric's solution won't work with the current graphene-django version(2.9.1) or greater than graphene-django 2.6.0 version.
Read more >[LIVE] Django GraphQL API with Python Graphene - YouTube
This is an edited livestream where I build a GraphQL API in Python's Django framework.It's a spaced repetition learning back-end to compare ...
Read more >Sorting - Graphene-Python
Graphene framework for Python. ... schema = graphene. ... The query has a sort argument which allows to sort over a different column(s)....
Read more >Integrating GraphQL API into a Django application - Section.io
This tutorial will focus on integrating a GraphQL API into a Django project and effectively using it to query data. GraphQL provides a ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@farnoodma Hey there! I had the same problem but finally, I fix it! Here is my code
and then, just use it instead of DjangoFilterConnectionField, like this:
and then, the query is something like this:
P.S: fix pagination bug
Update:
Mhs-220 solution won’t work with the current graphene-django version(2.9.1) or greater than graphene-django 2.6.0 version.
DjangoFilterConnectionField
methods are changed in the 2.7.0 version. For more details, you can check the changelogs hereThe solution will generate error,
connection_resolver() missing 1 required positional argument: 'info’
.I have modified the solution and it worked perfectly.