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"]