Reputation: 4933
I am new to Django 1.9, Rest Framework I have an models.py as follows:
class UniservedTeam(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Role = ArrayField(models.CharField(max_length=1000), blank=True,null=True)
ContactNumber = models.CharField(max_length=100)
What I have tried is:-
from rest_framework import serializers
from django.contrib.auth.models import User
from models import UniservedTeam
class UniservedTeamSerializer(serializers.ModelSerializer):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Role = ArrayField(models.CharField(max_length=1000), blank=True,null=True)
ContactNumber = serializers.CharField(max_length=100)
class Meta:
model = User
fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'city')
What serializer's methods I should use for Id
and Role
fields?
How do I write serializer for post and get method?
If I remove 'id' and 'Role' field from serializer like below:-
class UniservedTeamSerializer(serializers.ModelSerializer):
# city = serializers.CharField(source=UniservedTeam.city)
# id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
# Role = ArrayField(models.CharField(max_length=1000), blank=True,null=True)
ContactNumber = serializers.CharField(source='UniservedTeam.ContactNumber')
class Meta:
model = User
fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'ContactNumber')
My shell output is as follows:
>>> from projectmanagement.serializers import UniservedTeamSerializer
>>> users = UniservedTeam.objects.all()
>>> serializer = UniservedTeamSerializer(users, many=True)
>>> serializer
UniservedTeamSerializer([<UniservedTeam: UniservedTeam object>], many=True):
id = IntegerField(label='ID', read_only=True)
username = CharField(help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, validators=[<django.core.validators.RegexValidator object>, <UniqueValidator(queryset=User.objects.all())>])
password = CharField(max_length=128)
first_name = CharField(allow_blank=True, max_length=30, required=False)
last_name = CharField(allow_blank=True, max_length=30, required=False)
email = EmailField(allow_blank=True, label='Email address', max_length=254, required=False)
ContactNumber = CharField(source='UniservedTeam.ContactNumber')
Error:-
>>> serializer.data
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/piyush/.environments/awsd/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 674, in data
ret = super(ListSerializer, self).data
File "/home/piyush/.environments/awsd/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 239, in data
self._data = self.to_representation(self.instance)
File "/home/piyush/.environments/awsd/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 614, in to_representation
self.child.to_representation(item) for item in iterable
File "/home/piyush/.environments/awsd/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 463, in to_representation
attribute = field.get_attribute(instance)
File "/home/piyush/.environments/awsd/local/lib/python2.7/site-packages/rest_framework/fields.py", line 422, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `username` on serializer `UniservedTeamSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `UniservedTeam` instance.
Original exception text was: 'UniservedTeam' object has no attribute 'username'.
Upvotes: 0
Views: 3442
Reputation: 9235
Primarily, when defining onetonone fields, related_name constraints are very much helpful, than we think. You need to make a couple changes in your model and serializer.
In models.py,
class UniservedTeam(models.Model):
user = models.OneToOneField(User, related_name='userprofile', on_delete=models.CASCADE)
Define related_name for user.
In your serializers,
class UserSerializer(serializers.ModelSerializer):
ContactNumber = serializers.CharField(source='userprofile.ContactNumber')
class Meta:
model = User
fields = ('id', 'username', 'password', 'first_name', 'ContactNumber')
Hope this works
EDIT
The related_name attribute specifies the name of the reverse relation from theUser model back to your model.
If you don't specify a related_name, Django automatically creates one using the name of your model with the suffix_set, for instance User.map_set.all().
If you do specify, e.g. related_name=maps on the User model, User.map_set will still work, but the User.maps. syntax is obviously a bit cleaner and less clunky; so for example, if you had a user object current_user, you could use current_user.maps.all() to get all instances of your Map model that have a relation to current_user.
For documentation, here
Also, if you want to access all of your fields of Userprofile in your User model, you could just pass the serializer into the User serializer like this,
class UniservedTeamSerializer(serializers.ModelSerializer):
city = serializers.CharField(source=UniservedTeam.city)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Role = ArrayField(models.CharField(max_length=1000), blank=True,null=True)
ContactNumber = serializers.CharField(source='UniservedTeam.ContactNumber')
And in your UserSerializer,
class UserSerializer(serializers.ModelSerializer):
user_profile_details = UniservedTeamSerializer(source='userprofile', many=True)
class Meta:
model = User
fields = ('id', 'username', 'password', 'first_name', 'user_profile_details')
The serializer output will now have UniservedTeamSerializer data under the tag, user_profile_details.
For more about serializers, the documentation covers pretty much everything about it.
UPDATE
From the docs
Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
The serializers in REST framework work very similarly to Django's Form and ModelForm classes. We provide a Serializer class which gives you a powerful, generic way to control the output of your responses, as well as a ModelSerializer class which provides a useful shortcut for creating serializers that deal with model instances and querysets.
Serializers convert objects into native python datatypes, to finalise the serialization process, data needs to be rendered into the corresponding format(json, xml).
Upvotes: 2