graphene-django-extras
graphene-django-extras copied to clipboard
Using "__in" filter lookup expression
Hello,
I would like to use "__in" as a filter lookup expression but I am getting errors. I have a manyToMany relation on a model:
class A(models.Model):
b_list = models.ManyToManyList(B)
class AObject(DjangoObjectType):
class Meta:
model = A
filter_fields = {
"b_list": ("in",)
}
class Query(graphene.ObjectType):
as = DjangoFilterPaginateListField(AObject, pagination=LimitOffsetGraphqlPagination())
if I try to query with b_list_in I get the following error: 'list' object has no attribute 'split'
Thank you!
here is the complete error log:
Traceback (most recent call last):
File "G:\dev\intellibeer\backend\env\lib\site-packages\promise\promise.py", line 489, in _resolve_from_executor
executor(resolve, reject)
File "G:\dev\intellibeer\backend\env\lib\site-packages\promise\promise.py", line 756, in executor
return resolve(f(*args, **kwargs))
File "G:\dev\intellibeer\backend\env\lib\site-packages\graphql\execution\middleware.py", line 75, in make_it_promise
return next(*args, **kwargs)
File "G:\dev\intellibeer\backend\env\lib\site-packages\graphene_django_extras\fields.py", line 239, in list_resolver
qs = filterset_class(data=filter_kwargs, queryset=qs, request=info.context).qs
File "G:\dev\intellibeer\backend\env\lib\site-packages\django_filters\filterset.py", line 236, in qs
self.errors
File "G:\dev\intellibeer\backend\env\lib\site-packages\django_filters\filterset.py", line 213, in errors
return self.form.errors
File "G:\dev\intellibeer\backend\env\lib\site-packages\django\forms\forms.py", line 175, in errors
self.full_clean()
File "G:\dev\intellibeer\backend\env\lib\site-packages\django\forms\forms.py", line 376, in full_clean
self._clean_fields()
File "G:\dev\intellibeer\backend\env\lib\site-packages\django\forms\forms.py", line 388, in _clean_fields
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
File "G:\dev\intellibeer\backend\env\lib\site-packages\django_filters\widgets.py", line 201, in value_from_datadict
return value.split(',')
graphql.error.located_error.GraphQLLocatedError: 'list' object has no attribute 'split'
I looked through the code a bit and it appears that graphene-django-extras always sends a list to django-filters. If I send [1,2,3,4], django-filters receives a list of size 4 containing the 4 numbers. If I send "1,2,3,4", django-filters receives a list of size 1 containing the string.
ok so I randomly found a solution. using filter_fields doesn't work, but I can achieve the same result with a custom filterSet:
class AFilter(django_filters.FilterSet):
class Meta:
model = A
fields = {
"b_list": ["in"],
}
class A(models.Model):
b_list = models.ManyToManyList(B)
class AObject(DjangoObjectType):
class Meta:
model = A
filterset_class = AFilter
class Query(graphene.ObjectType):
as = DjangoFilterPaginateListField(AObject, pagination=LimitOffsetGraphqlPagination())
using the argument b_List_In:"1,2"
then works.
nevermind. It works on one-to-many relationships, but not many-to-many, which is my main use-case.
For now I use __in on the ids and I had to change the code (default behavior is that graphene throws an error because [1,2] or "1,2" aren't Floats.):
class InFilter(django_filters.BaseInFilter):
pass
# Add this in the filter class:
class AFilter(django_filters.FilterSet):
bList_Id__in = InFilter(field_name='b_list__id', lookup_expr='in')
class Meta:
model = A
fields = {
...
}
Hi @sbernier1 , have you found a final solution for this? How do you make a query where you provide a list and query runs returns all results matching that list; something like id_list = [1, 2, 3, 4] and the query returns all objects where their id's are 1, 2, 3, and 4.
Hi, I used the solution I posted for a while, but I encountered other problems with graphene-django-extras (I don't remember which ones) so I ended up using the relay-style graphql instead, because it has tons more functionalities and it works with Apollo.