如何在 Django 中组合两个或多个具有自定义字段但具有相同模型的序列化器?

Om *_*yap 1 api django serialization django-rest-framework

我正在尝试创建一个具有两个字段的序列化器类:名称、主题,但在某种情况下,我需要为每个字段创建两个不同的序列化器,因为 NameSerializer 和 subjectSerializer 将在许多不同的地方使用。因此,如果我使用它们,我只需通过序列化器即可获取详细信息,而不必每次都创建 SerializerMethodField。对于我的NameSerializer和SubjectSerializer,我使用SerializerMethod字段,我不直接访问这些字段。我可以使用单个序列化器直接获取数据,但当我在一个组合序列化器下使用两个序列化器时,我无法访问数据。

模型.py

class UserAccount(models.Model):
    name = models.CharField(max_length = 200)
    subject = models.CharField(max_length = 200 )
Run Code Online (Sandbox Code Playgroud)

views.py 有序列化器以及函数viewsviews.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 
    )
Run Code Online (Sandbox Code Playgroud)

有没有办法使用同一模型的两个不同序列化器来获取同一模型的数据。或者我做错了什么。这两个序列化器可以很好地分开工作。

错误 :

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

Run Code Online (Sandbox Code Playgroud)

如果我分别运行两个序列化程序,它们会很好地工作。但在 FullSerializer 中使用时则不然

NKS*_*KSM 6

您可以通过继承来扩展和重用序列化器。这允许您在父类上声明一组通用的字段或方法,然后可以在许多序列化程序中使用它们。

\n

还可以Field通过将名称设置为子类来声明性地删除/覆盖从父类继承的内容None

\n

为你:

\n
class NameSerializer(serializers.ModelSerializer):\n    the_name = serializers.SerializerMethodField("getName")\n\n    ...\n\n    def getName(self,  object):\n        return "__"+str(object.name)+"__"\n\n\nclass SubjectSerializer(serializers.ModelSerializer):\n    the_subject = serializers.SerializerMethodField("get_the_subject")\n\n    ...\n\n    def get_the_subject(self , object) : \n        return "__"+str(object.subject)+"__"\n\n\n                          \xe2\xac\x87\xef\xb8\x8f             \xe2\xac\x87\xef\xb8\x8f\nclass FullSerializer(NameSerializer, SubjectSerializer):\n    # To remove parent fields\n    the_name = None\n    the_subject = None\n    # Than you can define your fields\n    some_name = serializers.SerializerMethodField("getName")\n    some_subject = serializers.SerializerMethodField("get_the_subject")\n\n    class Meta : \n        model = UserAccount\n        fields = ["some_name" , "some_subject"]\n\n
Run Code Online (Sandbox Code Playgroud)\n