{"action":"created","issue":{"url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/2442","labels_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/2442/labels{/name}","comments_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/2442/comments","events_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/2442/events","html_url":"https://github.com/tomchristie/django-rest-framework/issues/2442","id":55099018,"number":2442,"title":"Serializers many to many field not reflecting edits made in PUT/PATCH if prefetch_related used","user":{"login":"chrismcband","id":196567,"avatar_url":"https://avatars.githubusercontent.com/u/196567?v=3","gravatar_id":"","url":"https://api.github.com/users/chrismcband","html_url":"https://github.com/chrismcband","followers_url":"https://api.github.com/users/chrismcband/followers","following_url":"https://api.github.com/users/chrismcband/following{/other_user}","gists_url":"https://api.github.com/users/chrismcband/gists{/gist_id}","starred_url":"https://api.github.com/users/chrismcband/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chrismcband/subscriptions","organizations_url":"https://api.github.com/users/chrismcband/orgs","repos_url":"https://api.github.com/users/chrismcband/repos","events_url":"https://api.github.com/users/chrismcband/events{/privacy}","received_events_url":"https://api.github.com/users/chrismcband/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/tomchristie/django-rest-framework/labels/Documentation","name":"Documentation","color":"444444"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":16,"created_at":"2015-01-22T00:39:09Z","updated_at":"2015-11-07T09:20:46Z","closed_at":null,"body":"If you use a viewset with a queryset using prefetch_related, any update to those prefetched many to many fields is not reflected in the response to the client, although the changes have been saved to the database.\r\n\r\nSee below code for very simple example:\r\n\r\n```python\r\nfrom django.conf.urls import patterns, include, url\r\nfrom django.contrib import admin\r\nfrom django.contrib.auth.models import User\r\nfrom rest_framework import serializers, viewsets, routers\r\n\r\n\r\nclass UserSerializer(serializers.ModelSerializer):\r\n    class Meta:\r\n        model = User\r\n        fields = ('id', 'username', 'email', 'groups')\r\n\r\n\r\nclass UserViewSet(viewsets.ModelViewSet):\r\n    queryset = User.objects.all().prefetch_related('groups')\r\n    serializer_class = UserSerializer\r\n\r\n\r\nrouter = routers.DefaultRouter()\r\nrouter.register(r'users', UserViewSet)\r\n\r\nurlpatterns = patterns('',\r\n    url(r'^', include(router.urls)),\r\n    url(r'^api-auth/', include('rest_framework.urls',\r\n                               namespace='rest_framework')),\r\n    url(r'^admin/', include(admin.site.urls)),\r\n)\r\n```\r\n\r\nWith the above code, assume there is an existing user with 2 groups assigned:\r\n```json\r\n{\r\n    \"id\": 1, \r\n    \"username\": \"chris\", \r\n    \"email\": \"chris@example.com\", \r\n    \"groups\": [\r\n        1,\r\n        2\r\n    ]\r\n}\r\n```\r\nSubmitting a PUT to /users/1/ changing groups to `[1]`, the response will still show groups as `[1, 2]`, but if you then did a GET request for /users/1/ you would see the reflected changes.\r\n\r\nYou can see this behaviour using the browseable api also.\r\n\r\nRemoving prefetch_related from the queryset restores normal behaviour and edits are again reflected in the response.\r\n\r\nThis example is very trivial, but if people are using prefetch_related to try and optimise their database queries they may encounter this issue."},"comment":{"url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/comments/154668070","html_url":"https://github.com/tomchristie/django-rest-framework/issues/2442#issuecomment-154668070","issue_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/2442","id":154668070,"user":{"login":"aaugustin","id":788910,"avatar_url":"https://avatars.githubusercontent.com/u/788910?v=3","gravatar_id":"","url":"https://api.github.com/users/aaugustin","html_url":"https://github.com/aaugustin","followers_url":"https://api.github.com/users/aaugustin/followers","following_url":"https://api.github.com/users/aaugustin/following{/other_user}","gists_url":"https://api.github.com/users/aaugustin/gists{/gist_id}","starred_url":"https://api.github.com/users/aaugustin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aaugustin/subscriptions","organizations_url":"https://api.github.com/users/aaugustin/orgs","repos_url":"https://api.github.com/users/aaugustin/repos","events_url":"https://api.github.com/users/aaugustin/events{/privacy}","received_events_url":"https://api.github.com/users/aaugustin/received_events","type":"User","site_admin":false},"created_at":"2015-11-07T09:20:46Z","updated_at":"2015-11-07T09:20:46Z","body":"@tomchristie This is the issue we discussed on Tuesday."}}