Search code examples
django-rest-frameworkforeign-keysdjango-generic-viewsdjango-serializer

How to get and display all child objects in parent serializer in DRF


I have 3 different serializers for 3 different views of parent as well as child object. The views are CreateAPIView, ListAPIView, RetrieveAPIView.

So my CreateAPIView has one serializer for creating an object, ListAPIView has one serializer for listing the objects, and RetrieveAPIView has one for showing the object's details. And this is true for child as well as for parent object.

How do I list all the child objects in the parent object that are related to it? That means in RetrieveAPIView of parent I want to show ListAPIView of its children.

models:

class Boards(models.Model):

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    name = models.CharField(max_length=50, blank=False, null=False, unique=True)
    slug = models.SlugField()

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Boards, self).save(*args, **kwargs)

class Lists(models.Model):

    name = models.CharField(max_length=50, blank=False, null=False, unique=True)
    slug = models.SlugField()
    board = models.ForeignKey(Boards, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Lists, self).save(*args, **kwargs)

Serializers:

class BoardCreateSerializer(ModelSerializer):

    # user = request.user
    class Meta:
        model = Boards
        fields = ['name']

class BoardListSerializer(ModelSerializer):

    url = HyperlinkedIdentityField(
        view_name = 'trello:board-detail',
        lookup_field = 'slug',
    )
    user = SerializerMethodField()

    class Meta:
        model = Boards
        fields = ['url', 'name', 'user']

    def get_user(self, obj):
        return str(obj.user.username)

class BoardDetailSerializer(ModelSerializer):

    user = SerializerMethodField()
    
    class Meta:
        model = Boards
        fields = ['id', 'name', 'user']

    def get_user(self, obj):
        return str(obj.user.username)

And similarly, I've serializers for lists as well.(boards- parent object, lists-children).

How do I show all the lists in the detail view of Boards that are related to it?


Solution

  • There are different ways you can do this:

    1. Use the source argument by adding this field to BoardDetailSerializer:

      class BoardDetailSerializer(ModelSerializer):
          user = SerializerMethodField()
          lists = ListSerializer(
              source='Lists_set',
              many=True
          )
          class Meta:
              model = Boards
              fields = ['id', 'name', 'user', 'lists']
      
          def get_user(self, obj):
              return str(obj.user.username)
      
    2. You can also use SerializerMethodField() the same way you did for user. In the method, you need to pass the list through the serializer and obtain the data which will be in json format(assuming you're using the default json renderer)