如何序列化 Django 模型中的多个对象并在每个对象的输出 JSON 中添加动态计算的数据?

How to serialize multiples objects from a Django model and add dynamically computed data in outputed JSON for each object?

我正在将 Laravel PHP 代码移植到 Python Django/Django Rest Framework。

我的端点将输出 JSON.

我需要输出很多对象,但我需要为每个对象添加额外的计算值。 我怎样才能做到这一点?

比如我的模型是:

from django.db import models
from rest_framework.serializers import ModelSerializer

class MyObject(models.Model):
    name = models.CharField(max_length=255)
    score = models.IntegerField()

class MyObjectSerializer(ModelSerializer):
    class Meta:
        model = MyObject
        fields = ( 'name', 'score' )

我使用 MyObject.objects.all()(或过滤器)检索了一个查询集。 对于我的查询集中的每个 MyObject,我计算一个额外的值,称为 'stats',我想在我的 JSON 输出中输出它。

例如,如果我有 2 个对象 MyObject(name='foo',score='1') 和 MyObject(name='bar',score='2'),我将计算每个对象的统计值。

我的 JSON 输出应该是这样的:

{
   { 
       'name': 'foo',
       'score': 1,
       'stats': 1.2
   },
   { 
       'name': 'bar',
       'score': 2,
       'stats': 1.3
   },
}

最干净的方法是什么?

我可以为每个 MyObject 设置一个循环,使用序列化器一个一个地序列化每个 MyObject,并为此对象创建和更新字典,添加 'stats' 键。 我担心性能。

如果我只计算某些对象的统计值,混合 2 种输出怎么办?

您可以使用 SerializerMethodField:

class MyObjectSerializer(ModelSerializer):
    stat = SerializerMethodField()

    class Meta:
        model = MyObject
        fields = ( 'name', 'score', 'stat' )

    def get_stat(self, obj):
        # obj is the model instance (it passes only one even if many=True)
        # do calculations with obj and return the value
        return None

如果 stat 字段使用 related/foreign 关键模型时性能是一个问题,您可以使用注释或 select_related/prefetch_related。使用注释更有效,但根据需要可能难以创建。

如果可以注释,您可以使用其他序列化程序字段,例如:

class MyObjectSerializer(ModelSerializer):
    stat = FloatField(read_only=True)

    class Meta:
        model = MyObject
        fields = ( 'name', 'score', 'stat' )

除了@kyell 写的,你还可以使用@属性装饰器和return你的计算数据在模型中创建一个属性,这个属性总是只读。