Reputation: 319
I have two models
Auth User model and UserProfile
UseProfile is:
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
name = models.CharField(_lazy(u'Name'), max_length=255)
For which I am using these serializers:
from rest_framework import serializers
from django.contrib.auth.models import User
from oneanddone.users.models import UserProfile
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('name',)
class UserSerializer(serializers.ModelSerializer):
profile = serializers.RelatedField()
class Meta:
model = User
fields = ('id', 'username', 'email', 'groups', 'profile')
The views for both serializers are:
class UserListAPI(generics.ListCreateAPIView):
"""
API endpoint used to get a complete list of users
and create a new user.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetailAPI(generics.RetrieveUpdateDestroyAPIView):
"""
API endpoint used to get, update and delete user data.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
lookup_field = 'email'
The nested serializer works fine for create/delete queries but for an update query like:
pdata = {"username":"testusername", "email":"[email protected]","profile":[{"name":"Changed Name"}]}
requests.patch('http://localhost:8000/api/v1/user/[email protected]/',data=json.dumps(pdata), headers={'Authorization':'Token bd876bfa04843c6ce1b82c84e27cd510f68dfbbd','Content-Type': 'application/json'}).text
I get an error saying 'UserProfile' object is not iterable. Traceback: http://pastebin.com/RA7JWFua
Can update like this be done with just nested serializer ? Please also give the custom code that I will have to add to make it work.
Upvotes: 0
Views: 1335
Reputation: 319
I got this working by making the following changes to Serializers and Views.
Serializers for both models:
from django.contrib.auth.models import User
from rest_framework import serializers
from oneanddone.users.models import UserProfile
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('name', 'username', 'privacy_policy_accepted')
class UserSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer(required=False, many=False)
class Meta:
model = User
fields = ('id', 'username', 'email', 'groups', 'profile')
Views for both serializers:
class UserDetailAPI(generics.RetrieveUpdateDestroyAPIView):
"""
API endpoint used to get, update and delete user data.
"""
lookup_field = 'email'
queryset = User.objects.all()
serializer_class = UserSerializer
class UserListAPI(generics.ListCreateAPIView):
"""
API endpoint used to get a complete list of users
and create a new user.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
And the update query can be written on similar lines like:
# Change Profile Data(name, username, privacy_policy_accepted)
changed_data = {'username': 'testname', 'email': '[email protected]',
'profile': {'name': 'Changed Test Name', 'username': 'testname123', 'privacy_policy_accepted': False}}
response = self.client.patch(user_uri, changed_data, format='json')
Disclaimer: All these code snippets are now a part of an application under Mozilla organization and released under the Mozilla license.
Links to original code can be found here:
Serializers , Views , Unit Tests for Profile Update
Upvotes: 0