Skip to content

Commit

Permalink
Fix UpdateModelMixin to work when no queryset is defined
Browse files Browse the repository at this point in the history
  • Loading branch information
browniebroke committed Mar 19, 2024
1 parent 77ef27f commit 89c79d6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
11 changes: 6 additions & 5 deletions rest_framework/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,14 @@ def update(self, request, *args, **kwargs):
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)

queryset = self.filter_queryset(self.get_queryset())
if queryset._prefetch_related_lookups:
if hasattr(instance, '_prefetched_objects_cache'):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance,
# and then re-prefetch related objects
# forcibly invalidate the prefetch cache on the instance
instance._prefetched_objects_cache = {}
prefetch_related_objects([instance], *queryset._prefetch_related_lookups)
queryset = self.filter_queryset(self.get_queryset())
if getattr(queryset, '_prefetch_related_lookups', None):
# And then re-prefetch related objects
prefetch_related_objects([instance], *queryset._prefetch_related_lookups)

return Response(serializer.data)

Expand Down
15 changes: 15 additions & 0 deletions tests/test_prefetch_related.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ class UserUpdateWithoutPrefetchRelated(generics.UpdateAPIView):
serializer_class = UserSerializer


class UserRetrieveWithoutQuerySet(generics.RetrieveUpdateAPIView):
serializer_class = UserSerializer

def get_object(self):
return User.objects.get(pk=self.kwargs['pk'])


class TestPrefetchRelatedUpdates(TestCase):
def setUp(self):
self.user = User.objects.create(username='tom', email='[email protected]')
Expand Down Expand Up @@ -90,3 +97,11 @@ def test_db_query_count(self):
)
with self.assertNumQueries(16):
UserUpdateWithoutPrefetchRelated.as_view()(request, pk=self.user.pk)

def test_can_update_without_queryset(self):
request = factory.patch('/', {'username': 'new'})
response = UserRetrieveWithoutQuerySet.as_view()(request, pk=self.user.pk)
assert response.data['id'] == self.user.id
assert response.data['username'] == 'new'
self.user.refresh_from_db()
assert self.user.username == 'new'

0 comments on commit 89c79d6

Please sign in to comment.