KeyError when using django-filter>=2.0
florimondmanca opened this issue · 2 comments
Steps to Reproduce
Note: the model I was using was replaced with a generic MyModel
(for confidentiality concerns), so I have not run this code myself but hopefully it should be enough to reproduce the issue.
# models.py
class MyModel(models.Model):
name = models.TextField()
# serializers.py
from rest_framework import serializers
from .models import MyModel
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('name',)
# filters.py
class MyModelFilter(filters.FilterSet):
class Meta:
model = MyModel
fields = {
'name': ['exact'],
}
# views.py
from rest_framework import mixins
from rest_framework_filters.backends import DjangoFilterBackend
from .models import MyModel
from .serializers import MyModelSerializer
from .filters import MyModelFilter
class MyModelViewSet(mixins.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
filter_backends = (DjangoFilterBackend,)
search_fields = ('name',)
filter_class = MyModelFilter
# urls.py
import myapp.views
...
router.register('foo', myapp.views.MyModelViewSet)
...
Then, in a test, performing:
response = self.client.get('/foo/', data={'search': 'name'})
raises the following error:
Traceback (most recent call last):
File "/app/tests/test_api.py", line 156, in test_foo
response = self.client.get('/foo/', data={'search': 'name'})
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 292, in get
response = super(APIClient, self).get(path, data=data, **extra)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 209, in get
return self.generic('GET', path, **r)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 238, in generic
method, path, data, content_type, secure, **extra)
File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 416, in generic
return self.request(**r)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 289, in request
return super(APIClient, self).request(**kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 241, in request
request = super(APIRequestFactory, self).request(**kwargs)
File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 501, in request
six.reraise(*exc_info)
File "/usr/local/lib/python3.6/site-packages/django/utils/six.py", line 686, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/mixins.py", line 40, in list
queryset = self.filter_queryset(self.get_queryset())
File "/usr/local/lib/python3.6/site-packages/rest_framework/generics.py", line 152, in filter_queryset
queryset = backend().filter_queryset(self.request, queryset, self)
File "/usr/local/lib/python3.6/site-packages/rest_framework_filters/backends.py", line 34, in filter_queryset
return super(DjangoFilterBackend, self).filter_queryset(request, queryset, view)
File "/usr/local/lib/python3.6/site-packages/django_filters/rest_framework/backends.py", line 96, in filter_queryset
return filterset.qs
File "/usr/local/lib/python3.6/site-packages/rest_framework_filters/filterset.py", line 266, in qs
qs = super(FilterSet, self).qs
File "/usr/local/lib/python3.6/site-packages/django_filters/filterset.py", line 237, in qs
qs = self.filter_queryset(qs)
File "/usr/local/lib/python3.6/site-packages/django_filters/filterset.py", line 224, in filter_queryset
queryset = self.filters[name].filter(queryset, value)
KeyError: 'name'
Previously, the KeyError
was not raised and the filtering worked perfectly fine.
Environment
Docker image: python:3.6
Possible Solution
I am using django-rest-framework-filters==0.10.2
.
The setup.py
file in the repo states that it requires django_filter>=1.0
.
install_requires=[
'djangorestframework',
'django-filter>=1.0.0',
],
So, as django-filter==2.0
was released recently, when installing requirements from scratch again today, it installed that new version and the bug started to occur.
I was able to make it work again my explicitly stating django-filter<2.0
, which installs django-filter==1.1
. So it should be possible to quick-fix this by updating install_requires
in setup.py
, waiting for a release that supports django-filter>=2.0
.
Hi @florimondmanca. Yes, the issue is that the current release (0.10.2
) is not compatible with django-filter 2.0.0
. I'm finishing up a few related items for the 1.0 milestone (mostly updating the docs), and then the latest release should be compatible. I'll add a temporary note to the README so users are aware of the project status.
Hi @florimondmanca, I went ahead and created a 0.10.x
branch that sets the django-filter version to 1.x-compatible releases. @philipn should be able to create a post-release at some point.