I have problem with saving instance Live_In Nested Serializers in Django Rest Framework. Hope your guys help me! I think just a basic issue.
My Serializers:
I think it comes error when I write saving instance
class CityLiveInSerializer(ModelSerializer):
country = CharField(required=False, source='country.name')
class Meta:
model = City
fields = [
'name',
'slug',
'country'
]
class UserEditSerializer(ModelSerializer):
live_in = CityLiveInSerializer(source='profile.live_in')
about = serializers.CharField(source='profile.about')
class Meta:
model = User
fields = [
'username',
'live_in',
'about',
]
def update(self, instance, validated_data):
instance.username = validated_data.get('username', instance.username)
instance.save()
# Update Serializers Profile
if (validated_data.get('profile') is not None):
profile_data = validated_data.pop('profile')
profile = instance.profile
profile.about = profile_data.get('about', profile.about)
profile.save()
if (validated_data.get('live_in') is not None):
live_in_data = validated_data.pop('live_in')
try:
city = City.objects.get(name=live_in_data['name'])
except City.DoesNotExist:
city = City.objects.create(**live_in_data)
instance.profile.live_in = city
instance.profile.save()
return instance
My City Model (Live_in)
class City(BaseCity):
class Meta(BaseCity.Meta):
swappable = swapper.swappable_setting('cities', 'City')
class BaseCity(Place, SlugModel):
name = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
country = models.ForeignKey(swapper.get_model_name('cities', 'Country'), related_name='cities', null=True, blank=True)
My Profile Model
class Profile(models.Model):
# Extend User
user = models.OneToOneField(User, unique=True)
about = models.TextField(max_length=1000, default='', blank=True, null=True)
live_in = models.ForeignKey(City, null=True, blank=True, related_name="live_in")
Data sent by Postman (Json)
{ "live_in": { "name": "Encamp" } }
TraceError:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework/serializers.py" in data 263. self._data = self.to_representation(self.instance)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework/serializers.py" in to_representation 488. attribute = field.get_attribute(instance)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework/fields.py" in get_attribute 463. raise type(exc)(msg)
Exception Type: AttributeError at /api/v1/users/account/edit/ Exception Value: Got AttributeError when attempting to get a value for field live_in
on serializer UserEditSerializer
. The serializer field might be named incorrectly and not match any attribute or key on the User
instance. Original exception text was: 'User' object has no attribute 'live_in'.
First of all you dont need many=True
in this case. It required for related objects list, but you will pass only one city. Secondly live_in
is attribute of profile model so you need to update profile and add source argument:
live_in = CityLiveInSerializer(source="profile.live_in")
def update(self, instance, validated_data):
instance.username = validated_data.get('username', instance.username)
instance.save()
# Update Serializers Profile
if (validated_data.get('profile') is not None):
profile_data = validated_data.pop('profile')
profile = instance.profile
profile.about = profile_data.get('about', profile.about)
if (profile_data.get('live_in') is not None):
live_in_data = profile_data.pop('live_in')
try:
city = City.objects.get(name=live_in_data["name"])
except City.DoesNotExist:
city = City.objects.create(**live_in_data)
profile.live_in = city
profile.save()
return instance
In this case you need to allow create city without country, so you need to add null=True, blank=True to country attribute:
class BaseCity(Place, SlugModel):
name = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
country = models.ForeignKey(swapper.get_model_name('cities', 'Country'),
related_name='cities', null=True, blank=True)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.