Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 使用嵌套序列化程序时避免嵌套对象_Django_Django Models_Django Rest Framework - Fatal编程技术网

Django 使用嵌套序列化程序时避免嵌套对象

Django 使用嵌套序列化程序时避免嵌套对象,django,django-models,django-rest-framework,Django,Django Models,Django Rest Framework,我有两个模型,其中一个包含foreignKey关系中的另一个,我想制作一个API来返回这两个模型的组合,所以我尝试使用嵌套序列化器来添加相关模型,但是数据并不都在同一级别上,相关模型是第一个模型中的一个对象 这些是模型 class ModelOne(models.Model): 最后一个计数器=models.IntegerField() 第二类模型(models.Model): model\u one=models.ForeignKey(model one,on\u delete=models.

我有两个模型,其中一个包含foreignKey关系中的另一个,我想制作一个API来返回这两个模型的组合,所以我尝试使用嵌套序列化器来添加相关模型,但是数据并不都在同一级别上,相关模型是第一个模型中的一个对象

这些是模型

class ModelOne(models.Model):
最后一个计数器=models.IntegerField()
第二类模型(models.Model):
model\u one=models.ForeignKey(model one,on\u delete=models.CASCADE)
类别=型号.CharField(最大长度=64)
计数器类型=models.CharField(最大长度=32)
下面是序列化程序

class ModelOneSerializer(serializers.ModelSerializer):
类元:
model=ModelOne
fields=“\uuuu all\uuuuuu”
类ModelTwoSerializer(serializers.ModelSerializer):
model\u one=ModelOneSerializer(只读=True)
类元:
型号=型号二
fields=“\uuuu all\uuuuuu”
这将以

{
   "category" : ...,
   "counter_type" : ...,
   "model_one" : {
     "last_counter" : ...
   }
}
但是我不希望反应是那样的,我希望它更像这样

{
   "category" : ...,
   "counter_type" : ...,
   "last_counter" : ...,
}

有没有办法通过序列化程序实现这一点?

使用
SerializerMethodField

from rest_framework.fields import SerializerMethodField

class ModelTwoSerializer(serializers.ModelSerializer):
    last_counter = SerializerMethodField()

    class Meta:
        model = ModelTwo
        fields = "__all__"

    def get_last_counter(self, obj):
        return ModelOneSerializer(obj.model_one).data['last_counter']

当使用
SerializerMethodField
创建自定义字段(例如
field\u one
)时,必须创建一个名为
get\u field\u one
的方法,以便序列化程序自动检测此方法。

使用
SerializerMethodField

from rest_framework.fields import SerializerMethodField

class ModelTwoSerializer(serializers.ModelSerializer):
    last_counter = SerializerMethodField()

    class Meta:
        model = ModelTwo
        fields = "__all__"

    def get_last_counter(self, obj):
        return ModelOneSerializer(obj.model_one).data['last_counter']

当使用
SerializerMethodField
创建自定义字段(
field\u one
)时,您必须创建一个名为
get\u field\u one
的方法,以便序列化程序自动检测此方法。

您可以使用drf字段中的SerializerMethodField实现您想要执行的操作:

SerializerMethodField是一个只读字段,它在请求处理时通过调用所附加到的序列化程序类上的方法来计算其值。例如,对于您的案例,它将如下所示。请注意,已计算的last_计数器添加到序列化模型字段中

from rest_framework.fields import SerializerMethodField

class ModelTwoSerializer(serializers.ModelSerializer):
    last_counter = serializers.SerializerMethodField()

class Meta:
    model = ModelTwo
    fields = ["category", "counter_type", "last_counter"]

def get_last_counter(self, obj):
    return int(obj.model_one.last_counter)
SerializerMethodField接受方法\u名称,但使用默认模式命名这些方法通常更方便,即get\u。只需确保您的方法字段不会因任何繁重的提升操作而负担过重


您可以阅读官方文档的更多内容:

您可以使用drf字段中的SerializerMethodField实现您想要做的事情:

SerializerMethodField是一个只读字段,它在请求处理时通过调用所附加到的序列化程序类上的方法来计算其值。例如,对于您的案例,它将如下所示。请注意,已计算的last_计数器添加到序列化模型字段中

from rest_framework.fields import SerializerMethodField

class ModelTwoSerializer(serializers.ModelSerializer):
    last_counter = serializers.SerializerMethodField()

class Meta:
    model = ModelTwo
    fields = ["category", "counter_type", "last_counter"]

def get_last_counter(self, obj):
    return int(obj.model_one.last_counter)
SerializerMethodField接受方法\u名称,但使用默认模式命名这些方法通常更方便,即get\u。只需确保您的方法字段不会因任何繁重的提升操作而负担过重


您可以阅读有关官方文档的更多信息:

谢谢您的回答,当ModelOne只有一个字段时,这一点就起作用了,我如何在ModelOne中引入所有字段,我是否必须为ModelOne中的每个字段创建单独的字段?是的,不幸的是,这就是它的工作方式。我经常使用你最初提出的方法。是的,它引入了数据嵌套的下一个级别,但它只使用几行代码,可以在将来轻松维护。感谢您的回答,这在ModelOne只有一个字段时有效,我如何在ModelOne中引入所有字段,我是否必须为ModelOne中的每个字段创建单独的字段?是的,很遗憾,这就是它的工作原理。我经常使用你最初提出的方法。是的,它引入了数据嵌套的下一个级别,但它只使用几行代码,将来可以很容易地维护这些代码。