Custom serializer related field using Django Rest Framework

I recently was playing around with a dummy Django 2 project, and I came across a problem where the related field had to be more elaborative with more information. This is easy to be solved if you have two or three separate models with any kind of relationship defined, in my case it was a self referenced relationship model, as the model was designed to support question and answer series, where the answers could be questions as well, and an answer should have a parent, with an exception of parent node. Yes, this could be achieved using graph database or even easily using NoSQL, but had to try it in relational database.

The models.py:

class Topic(models.Model):
    text = models.CharField(max_length=100)
    parent = models.ForeignKey('self', related_name="children", blank=True,
                               null=True, on_delete=models.CASCADE)
    ref_id = models.IntegerField(default=0)

    class Meta:
        verbose_name = "Topics"
        verbose_name_plural = "Topics"

    def __unicode__(self):
        return '%s ' % self.text

    def __str__(self):
        return u'%s' % self.text

    def save(self, *args, **kwargs):
        if Topic.objects.filter(parent=self.parent).count() == 5:
            return
        else:
            super().save(*args, **kwargs)

The serializers.py:

class ListAllTopicsSerializer(serializers.ModelSerializer):

    children = serializers.StringRelatedField(many=True)

    class Meta:

        model = Topic

        fields = ('pk', 'text', 'parent', 'children')

The related view for listing all in json format was in views.py:

class ListTopicsApiView(ListAPIView):

    """

    This api view is to show question and its children

    """

    queryset = Topic.objects.all()

    serializer_class = ListALLTopicsSerializer

    def list(self, request, parent_id=None, child_id=None):

        queryset = self.get_queryset()

        serializer = ListALLTopicsSerializer(queryset, many=True)

        return Response(serializer.data)

As you could see from the model that it is parent self referenced field, so while listing all the fieldsthe serializer prints json something like this:

[ 
  { "pk": 49, 
    "text": "Are you hungry?", 
    "parent": null, 
    "children": [ "Yes", "No" ] 
  }, 
  { 
   "pk": 50, 
   "text": "Yes", 
   "parent": 49, 
    "children": [ "What would you like to eat?" ] 
   }, 
   { 
    "pk": 51, 
    "text": "No", 
    "parent": 49, 
    "children": [ "Ok. Call me when you're hungry." ] 
    },
    { 
     "pk": 53, 
     "text": "Ok. Call me when you're hungry.", 
     "parent": 51, "children": [] 
    }
]

As you could see, wherever we have children it takes the unicode field and puts as string, I wanted more information related to that field, and thats when I created a custom related field:

from rest_framework import serializers

class TopicRelatedField(serializers.RelatedField):

     def get_queryset(self):

         return Topic.objects.all()

     def to_representation(self, value):

         count = Topic.objects.filter(parent=value.pk).count()

         topic = Topic.objects.get(pk=value.pk)

         return{'pk': value.pk,'text': topic.text,'count': count}
# Change the ListALLTopicsSerializer to the following
class ListALLTopicsSerializer(serializers.ModelSerializer):

    children = TopicRelatedField(read_only=True, many=True)

    class Meta:

        model = Topic

        fields = ('pk', 'text', 'parent', 'children')

What this does is it returns more information for children field, for example, its primary key value in database and children related information, and parent too. So the resulting JSON now looks like:

[
    {
        "pk": 49,
        "text": "Are you hungry?",
        "parent": null,
        "children": [
            {
                "pk": 50,
                "text": "Yes",
                "count": 1
            },
            {
                "pk": 51,
                "text": "No",
                "count": 1
            }
        ]
    },
    {
        "pk": 50,
        "text": "Yes",
        "parent": 49,
        "children": [
            {
                "pk": 52,
                "text": "What would you like to eat?",
                "count": 5
            }
        ]
    },
    ..... and so forth..
]