Ross
Ross

Reputation: 2417

AttributeError when trying to created nested serializer in Django REST Framework

I have two models of sets, and cards. Theses models have one to many relationship where there are many cards in a single set. These model are join by a foreign key - each card has set_id which is equal to the id of the set. These IDs are UUID.

I am trying to create a serializer using Django REST Framework where I return the details of the set, as well as including all the cards that are part of the set.

error

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

serializers.py

class CardSerializers(serializers.ModelSerializer):
    class Meta:
        model = Card
        fields = ['id', 'number', 'name', 'set_id']

class SetSerializers(serializers.ModelSerializer):
    cards = CardSerializers()

    class Meta:
        model = Set
        fields = ['id', 'code', 'name', 'releaseDate','cards']

models.py

class Set(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ...

    objects = models.Manager()

    def __str__(self):
        return self.name

class Card(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ...
    set = models.ForeignKey(Set, on_delete=models.CASCADE, related_name='Cards', related_query_name='Cards')


    objects = models.Manager()

    def __str__(self):
        return self.name

views.py

class SetsIndividualData(ListAPIView):
    serializer_class = SetSerializers

    def get_queryset(self):
        setCode = self.kwargs.get('setCode')
        queryList = Set.objects.filter(code=setCode.upper())
        return queryList

Upvotes: 0

Views: 882

Answers (1)

gripep
gripep

Reputation: 379

There are a few mistakes in your code.

models.py:

In the Card model, the related_name of the FK should be lowercase as per below:

set = models.ForeignKey(Set, related_name="cards", on_delete=models.CASCADE)

serializers.py:

In your SetSerializers you had the right idea, but you need to be more specific with your CardSerializers, as you are describing a "to-many" relationship.

Please refer to the docs here: https://www.django-rest-framework.org/api-guide/relations/#nested-relationships

Moreover, from your views.py I can see you will only send GET requests, therefore you can have your cards to be read only. So the serializer card attribute would look like the below:

cards = CardSerializers(many=True, read_only=True)

views.py:

It looks like you want to retrieve a set by id. ListAPIView is the wrong generics, you should use RetrieveAPIView instead, as it provides a get method and is used to retrieve a single model instance.

Please refer to the docs for more information: https://www.django-rest-framework.org/api-guide/generic-views/#retrieveapiview

Upvotes: 1

Related Questions