Home > Net >  How to combine two or more serializers which have custom fields but have same model in Django?
How to combine two or more serializers which have custom fields but have same model in Django?

Time:09-17

I am trying to create a Serializer Class which have two fields : name , subject but in a case I need to create two different serializers for each of the fields because the NameSerializer and SubjectSerializer will be used in many different places . So if I use them , I can just get detials just via the Serializer and not creating SerializerMethodField every time . For my NameSerializer and SubjectSerializer I am using SerializerMethod field , i am not directly accessing the fields . I am able to get data directly using a single serializer but I am unable to acceess the data when I am using both the serializer under one Combined Serializer.

models.py

class UserAccount(models.Model):
    name = models.CharField(max_length = 200)
    subject = models.CharField(max_length = 200 )

the views.py have serializers as well as the function views views.py

from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import UserAccount

class NameSerializer(serializers.ModelSerializer):
    the_name = serializers.SerializerMethodField("getName")
    class Meta : 
        model = UserAccount
        fields = ["the_name"]
    def getName(self,  object):
        return "__" str(object.name) "__"

class SubjectSerializer(serializers.ModelSerializer):
    the_subject = serializers.SerializerMethodField("get_the_subject")
    class Meta :
        model = UserAccount
        fields = ["the_subject"]
    def get_the_subject(self , object) : 
        return "__" str(object.subject) "__"

class FullSerializer(serializers.ModelSerializer):
    some_name = NameSerializer()
    some_subject = SubjectSerializer()

    class Meta : 
        model = UserAccount
        fields = ["some_name" , "some_subject"]

@api_view(["GET"])
def theView(request , *args , **kwargs):
    userone = UserAccount.objects.get(id = 1)
    data = FullSerializer(userone).data
    return Response(
        data 
    )

Is there any way to get the data of the same model using two different serializers of same model . Or I am doing something wrong . The two serializers work separately nicely.

The error :

AttributeError: Got AttributeError when attempting to get a value for field `some_name` on serializer `FullSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `UserAccount` instance.
Original exception text was: 'UserAccount' object has no attribute 'some_name'.
[16/Sep/2022 12:08:38] "GET / HTTP/1.1" 500 115641

If I run the two serializers separately , they work nicely . But not when used in FullSerializer

CodePudding user response:

You can extend and reuse serializers through inheritance. This allows you to declare a common set of fields or methods on a parent class that can then be used in a number of serializers.

It is also possible to declaratively remove/override a Field inherited from a parent class by setting the name to be None on the subclass.

For you:

class NameSerializer(serializers.ModelSerializer):
    the_name = serializers.SerializerMethodField("getName")

    ...

    def getName(self,  object):
        return "__" str(object.name) "__"


class SubjectSerializer(serializers.ModelSerializer):
    the_subject = serializers.SerializerMethodField("get_the_subject")

    ...

    def get_the_subject(self , object) : 
        return "__" str(object.subject) "__"


                          ⬇️             ⬇️
class FullSerializer(NameSerializer, SubjectSerializer):
    # To remove parent fields
    the_name = None
    the_subject = None
    # Than you can define your fields
    some_name = serializers.SerializerMethodField("getName")
    some_subject = serializers.SerializerMethodField("get_the_subject")

    class Meta : 
        model = UserAccount
        fields = ["some_name" , "some_subject"]

  • Related