Invalidate any existing prefetch cache on PUT requests. (#4668)

This commit is contained in:
Tom Christie 2016-11-11 09:44:35 +00:00 committed by GitHub
parent 8bab7f8d58
commit 24791cb353
3 changed files with 31 additions and 5 deletions

View File

@ -187,7 +187,12 @@ As usual CSRF validation will only apply to any session authenticated views. Th
# RequestsClient
REST framework also includes a client for interacting with your application
using the popular Python library, `requests`.
using the popular Python library, `requests`. This may be useful if:
* You are expecting to interface with the API primarily from another Python service,
and want to test the service at the same level as the client will see.
* You want to write tests in such a way that they can also be run against a staging or
live environment. (See "Live tests" below.)
This exposes exactly the same interface as if you were using a requests session
directly.
@ -198,6 +203,10 @@ directly.
Note that the requests client requires you to pass fully qualified URLs.
## `RequestsClient` and working with the database
The `RequestsClient` class is useful if
## Headers & Authentication
Custom headers and authentication credentials can be provided in the same way

View File

@ -71,9 +71,8 @@ class UpdateModelMixin(object):
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# refresh the instance from the database.
instance = self.get_object()
serializer = self.get_serializer(instance)
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
return Response(serializer.data)

View File

@ -14,7 +14,7 @@ class UserSerializer(serializers.ModelSerializer):
class UserUpdate(generics.UpdateAPIView):
queryset = User.objects.all().prefetch_related('groups')
queryset = User.objects.exclude(username='exclude').prefetch_related('groups')
serializer_class = UserSerializer
@ -39,3 +39,21 @@ class TestPrefetchRelatedUpdates(TestCase):
'email': 'tom@example.com'
}
assert response.data == expected
def test_prefetch_related_excluding_instance_from_original_queryset(self):
"""
Regression test for https://github.com/tomchristie/django-rest-framework/issues/4661
"""
view = UserUpdate.as_view()
pk = self.user.pk
groups_pk = self.groups[0].pk
request = factory.put('/', {'username': 'exclude', 'groups': [groups_pk]}, format='json')
response = view(request, pk=pk)
assert User.objects.get(pk=pk).groups.count() == 1
expected = {
'id': pk,
'username': 'exclude',
'groups': [1],
'email': 'tom@example.com'
}
assert response.data == expected