0
votes

When creating a serializer in Django REST Framework, I understand that I can create a SerializerMethodField that creates a new read-only method for a model. For example:

class AnswerSerializer(serializers.ModelSerializer):
    likes_count = serializers.SerializerMethodField()

    class Meta:
        model = Answer
        exclude = ["a_field"]

    def get_likes_count(self,instance):
        return instance.voters.count()

A similar thing could also be done using a property or method in the models.py file:

class Answer(models.Model):

    @property
    def get_likes_count(self):
        return voters.count()

So my question is:

What are the pros and cons of each? I understand that SerializerMethodField is for read_only operations but aside from that are not sure.

Is it best practice to keep the models.py file for model fields only, and to use signals for update/create operations and serializers for read operations?

1
Properties on the model can be accessed from any instance of the class and are useful when the property is an integral attribute of the model that can/will be accessed from multiple different views or serializers. Defining it on the serializer limits it to just that particular serializer and it's subclasses which can be useful if you don't intend that attribute to be used anywhere else - Iain Shelvington

1 Answers

1
votes

One advantage to using the serializer approach instead of the @property approach is that you can use annotations on the queryset passed to the serializer

 AnswerSerializer(Answer.objects.annotate(likes_count=Count('voters')), many=True)

def get_likes_count(self, instance):
    return getattr(instance, 'likes_count', None) or instance.voters.count()

This way you can use annotations to reduce the number of queries you make and have a fall back that calculates the value anyway