Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework - Nested Serialization not working as expected

While using Django-REST-Framework, I am not able to display selected fields in a nested serialized object.

I am correctly able to serialize the entirety of the Address model, but I want only a few fields from Address, nested in my serialized Outlet. There is a

Got AttributeError when attempting to get a value for field outlet_address on serializer OutletSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Outlet instance. Original exception text was: 'Outlet' object has no attribute 'outlet_address'.

api_v1/models.py

class Address(models.Model):
    building = models.CharField(_("shop number, floor & building"), max_length=128)
    street = models.CharField(_("street"), max_length=128, blank=True)
    area = models.ManyToManyField(Area, related_name='address')
    city = models.ForeignKey(City, related_name='address')
    pin_code = models.CharField(_("PIN code"), max_length=6, default="")

    def __unicode__(self):
        return self.building + " " + self.street + " ..."


class Outlet(models.Model):
    name = models.CharField(max_length=100, blank=True)
    chain = models.ForeignKey(Chain, related_name='outlet', blank=True, null=True)
    organization = models.ForeignKey(Organization, blank=True, null=True)
    address = models.OneToOneField(Address, related_name='outlet_address')
    thumbnail = AjaxImageField(upload_to='thumbnails',
                               max_height=200,  #optional
                               max_width=200,  # optional
                               crop=True)  # optional
    date_created = models.DateTimeField(_('date created'), default=timezone.now)

    def __unicode__(self):
        return self.name

api_v1/serializers.py

from rest_framework import serializers
from api_v1.models import Outlet, Address

class AddressSerializer(serializers.ModelSerializer):
    #address_area = AreaSerializer(many=False)

    class Meta:
        model = Address
        fields = ('building', 'street',)
        depth = 3


class OutletSerializer(serializers.ModelSerializer):
    outlet_address = AddressSerializer(many=False)
    #area = serializers.CharField(source='address.area') #multiple levels of nesting?

    class Meta:
        model = Outlet
        fields = ('id', 'name', 'thumbnail', 'outlet_address')
        # fields = ('id', 'name', 'thumbnail', 'address') # this works
        depth = 3

At this point, it is unable to find the outlet_address attribute in the Outlet model while I expect it should be able to in the serializer.

Got AttributeError when attempting to get a value for field outlet_address on serializer OutletSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Outlet instance. Original exception text was: 'Outlet' object has no attribute 'outlet_address'.

As described on other answers, I have tried:

  1. adding many= to the ModelSerializer
  2. adding related_name= to all Models
like image 718
Pranab Avatar asked Oct 20 '15 03:10

Pranab


1 Answers

Try this:

from rest_framework import serializers
from api_v1.models import Outlet, Address

class AddressSerializer(serializers.ModelSerializer):

    class Meta:
        model = Address
        fields = ('building', 'street',)
        depth = 3


class OutletSerializer(serializers.ModelSerializer):
    address = AddressSerializer(many=False) # make it address, not outlet_address

    class Meta:
        model = Outlet
        fields = ('id', 'name', 'thumbnail', 'address') # make this address as well, not outlet_address
        depth = 3

The reason I would make the changes above is because the Outlet model does not have an attribute called "outlet_address", it has an attribute called "address".

See here for a similar issue: Django Rest framework keeps returning error on nested relationship

like image 171
SilentDev Avatar answered Sep 25 '22 15:09

SilentDev