How can I add my custom model function's value in my API

Issue

I’m trying to build my own poll app and the models have a lot of relation with each other and I need to count how many objects are in relation with some other objects so I need these custom function for it

Here’s the model with the custom functions:

class Poll(models.Model):

    title = models.CharField(max_length=255)
    is_active = models.BooleanField(default=True)
    is_available = models.BooleanField(default=True)
    date_created = models.DateTimeField(auto_now_add=True)

    def __str__(self):

        return self.title

    @property
    def total_votes(self):

        votes = 0

        for o in self.option_set.all():

            votes = votes + o.how_much_vote

            return votes
        
    @property
    def users_involved(self):

        list = []

        for o in self.option_set.all():

            for v in o.vote:

                list.append(v.user)
        
        return list
            
    @property
    def users_involved(self):

        users = []

        for o in self.option_set.all():

            for v in o.who_voted:

                users.append(v)
        
        return users

    @property
    def total_votes_each_option(self):

        dct = {}

        for o in self.option_set.all():

            dct[o.title]= o.how_much_vote

        return dct

My question is how do you include all of those custom functions total_votes, users_involved, etc to my api? because right now my api looks something like this:

{
    "id": 1,
    "title": "Which is the best frontend framework?",
    "is_active": true,
    "is_available": true,
    "date_created": "2021-07-13T14:08:17.709054Z"
}

which is expected but I want to know how do I add those extra value to make it look like this

{
    "id": 1,
    "title": "Which is the best frontend framework?",
    "is_active": true,
    "is_available": true,
    "date_created": "2021-07-13T14:08:17.709054Z",
    "total_votes": "some number",
    "users_involved": [...users]
}

Edit: here’s my serializer class

class PollSerializer(serializers.ModelSerializer):

    class Meta:

        model = Poll
        fields = '__all__'

Thank you very much

Solution

Simple way we can use SerializerMethodField

from rest_framework import serializers


class PollSerializer(serializers.ModelSerializer):
    total_votes = serializers.SerializerMethodField()
    users_involved = serializers.SerializerMethodField()

    class Meta:
        model = Poll
        fields = (
            'id',
            'title',
            'is_active',
            'is_available',
            'date_created',

            'total_votes',
            'users_involved',
        )

    def get_total_votes(self, poll):
        return poll.total_votes

    def get_users_involved(self, poll)
        return poll.users_involved

Please note that SerializerMethodField is read_only, cannot for write.
Also make sure your custom model functions well for loop processing, using select_related or prefetch_related.

Answered By – Mahrus Khomaini

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published