6

I've been trying to use a nested serializer with DRF but it won't display the related item in the output.

Here's my model.py :

class Categorie(models.Model):
    nom = models.CharField(max_length=100)

    def __unicode__(self):
        return unicode(self.nom)

class Item(models.Model):
    nom = models.CharField(max_length=100)
    disponible_a_la_vente = models.BooleanField(default = True)
    nombre = models.IntegerField()
    prix = models.DecimalField(max_digits=5, decimal_places=2)
    history = HistoricalRecords()

    categorie = models.ForeignKey(Categorie, models.CASCADE)


    class Meta:
        verbose_name = "item"
        verbose_name_plural = u"inventaire"

        ordering = ['categorie', 'nom']

    def __unicode__(self):
        return u'{nom} - {nombre}'.format(nom = self.nom, nombre = self.nombre)

and my serializers.py

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ('nom',)

class CategorieSerializer(serializers.ModelSerializer):
    items = ItemSerializer(many=True)

    class Meta:
        model = Categorie
        fields = ('nom', 'id', 'items')

The view i'm currently testing is very basic :

class InventaireDetail(generics.RetrieveAPIView):
    queryset = Categorie.objects.all()
    serializer_class = CategorieSerializer

but it gives the error:

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

I've been looking for a while now but i can't get it working even with the help of the doc.

1 Answer 1

10

Categorie.items does not exist. By default the reverse relation would get the name Categorie.item_set. You can fix that in two ways.

EITHER: add related_name to your foreign key.

class Item(models.Model):
    categorie = models.ForeignKey(Categorie, models.CASCADE, related_name='items')

OR: another solution is to change the CategorieSerializer

class CategorieSerializer(serializers.ModelSerializer):
    items = ItemSerializer(many = True, read_only=True, source='item_set')
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, obviously it was that. You saved me a lot of headaches.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.