Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a count field to a django rest framework serializer

I am serializing the built-in django Group model and would like to add a field to the serializer that counts the number of users in the group. I am currently using the following serializer:

class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = Group
        fields = ('id', 'name', 'user_set')

This returns the group ID and name and an array of users (user IDs) in the group:

{
    "id": 3,
    "name": "Test1",
    "user_set": [
      9
    ]
}

What I would like instead as output is something like:

{
    "id": 3,
    "name": "Test1",
    "user_count": 1
}

Any help would be appreciated. Thanks.

like image 481
David Brown Avatar asked Oct 26 '15 11:10

David Brown


People also ask

What does serializer Is_valid () do?

The .is_valid() method takes an optional raise_exception flag that will cause it to raise a serializers.ValidationError exception if there are validation errors.

How does Django validate data in serializer?

Validation in Django REST framework serializers is handled a little differently to how validation works in Django's ModelForm class. With ModelForm the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class.


3 Answers

A bit late but short answer. Try this

user_count = serializers.IntegerField(
    source='user_set.count', 
    read_only=True
)
like image 58
Lal Avatar answered Oct 20 '22 10:10

Lal


This should work

class GroupSerializer(serializers.ModelSerializer):

    user_count = serializers.SerializerMethodField()

    class Meta:
        model = Group
        fields = ('id', 'name','user_count')

    def get_user_count(self, obj):
        return obj.user_set.count()

This adds a user_count field to your serializer whose value is set by get_user_count, which will return the length of the user_set.

You can find more information on SerializerMethodField here: http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

like image 24
emre. Avatar answered Oct 20 '22 09:10

emre.


Everyone's answer looks great. And I would like to contribute another options here - to use @property if-and-only-if you can modify the target model.

Assume you can modify the Group model.

class Group(models.Model):

    @property
    def user_count(self):
        return self.user_set.count

Then you can simply add 'user_count' to fields in your serializer.

I'm using this approach but I'm thinking to switch to the serializer approach as other's answer here. Thanks everyone.

like image 3
John Pang Avatar answered Oct 20 '22 09:10

John Pang