Search code examples
pythondjangodjango-rest-frameworkdjango-serializer

Serializes ManyToMany relations in Django Rest Framework


I want to serializing ManyToMany fields. So, in the response for tje Application model should also the band and the band description listed. But I've got the following error message:

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

Anyone who knows why it doesnt work?

models.py

class Band(models.Model):
    """Database models for satellit's bands information"""

    band = models.CharField(max_length=3)
    description = models.CharField(max_length=255)
    in_satellite = models.ForeignKey('Satellite', on_delete=models.PROTECT, blank=True, null=True)
    wavelength = models.DecimalField(max_digits=4, decimal_places=0, default='0', help_text='Central wavelength (nm)')
    resolution = models.DecimalField(max_digits=4, decimal_places=0, default='0', help_text='Spatial resolution (m)')

    def __str__(self):
        return '%s | %s' % (self.in_satellite, self.band)


class Satellite(models.Model):
    """Database models for satellite information"""

    name = models.CharField(max_length=255)
    accr = models.CharField(max_length=3)
    operator = models.CharField(max_length=255, default='European Space Agency')

    def __str__(self):
        return self.name


class Indice(models.Model):
    """Database models for index information"""

    name = models.CharField(max_length=255)
    accr = models.CharField(max_length=10)
    description = models.TextField(max_length=255, blank=True, null=True)
    satellite_to_use = models.ForeignKey('Satellite', on_delete=models.PROTECT, blank=True, null=True)
    needed_bands = models.ManyToManyField(Band)

    def __str__(self):
        return self.name


class Application(models.Model):
    """Database models for application information"""

    name = models.CharField(max_length=255)
    description = models.TextField(max_length=255, blank=True, null=True)
    indice_to_use = models.ForeignKey('Indice', on_delete=models.PROTECT, blank=True, null=True)

    def __str__(self):
        return self.name

serializers.py

class BandSerializer(serializers.ModelSerializer):

    class Meta:
        model = Band
        fields = ['band', 'description', ]

class OsdSerializer(serializers.ModelSerializer):
    bands = BandSerializer()

    class Meta:
        model = Application
        fields = ['name', 'description', 'bands',]

views.py

class OsdView(APIView):
    def get(self, request):
        applications = Application.objects.all()
        serializer = OsdSerializer(applications, many=True)
        return Response({"Your open space data:": serializer.data})

Solution

  • IIUC, you need to change the OsdSerializer to specify the relation you want to include in the serialized data:

    bands = BandSerializer(source='indice_to_use.needed_bands', many=True)