我想序列化一个模型,但想包括一个额外的字段,需要在模型实例上做一些数据库查询要序列化:

class FooSerializer(serializers.ModelSerializer):
  my_field = ... # result of some database queries on the input Foo object
  class Meta:
        model = Foo
        fields = ('id', 'name', 'myfield')

正确的做法是什么?我看到你可以传递额外的“上下文”序列化器,是正确的答案,在上下文字典中传递额外的字段?

使用这种方法,获取我需要的字段的逻辑将不包含在序列化器定义中,这是理想的,因为每个序列化实例都需要my_field。在DRF序列化器文档的其他地方,它说“额外的字段可以对应于模型上的任何属性或可调用”。我说的是“额外字段”吗?

我是否应该在Foo的模型定义中定义一个返回my_field值的函数,并在序列化器中将my_field连接到该可调用对象?它看起来像什么?

如果有必要,我很乐意澄清问题。


当前回答

在序列化器类中添加以下内容:

def to_representation(self, instance):
    representation = super().to_representation(instance)
    representation['package_id'] = "custom value"
    return representation

其他回答

我认为SerializerMethodField是你要找的:

class FooSerializer(serializers.ModelSerializer):
  my_field = serializers.SerializerMethodField('is_named_bar')

  def is_named_bar(self, foo):
      return foo.name == "bar" 

  class Meta:
    model = Foo
    fields = ('id', 'name', 'my_field')

http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

class Demo(models.Model):
    ...
    @property
    def property_name(self):
        ...

如果你想使用相同的属性名:

class DemoSerializer(serializers.ModelSerializer):
    property_name = serializers.ReadOnlyField()
    class Meta:
        model = Product
        fields = '__all__' # or you can choose your own fields

如果你想使用不同的属性名,只需更改这个:

new_property_name = serializers.ReadOnlyField(source='property_name')

在序列化器类中添加以下内容:

def to_representation(self, instance):
    representation = super().to_representation(instance)
    representation['package_id'] = "custom value"
    return representation

尽管这不是作者想要的,但它仍然可以被认为对这里的人有用:

如果您正在使用.save() ModelSerializer的方法,您可以将**kwargs传递给它。这样,您就可以保存多个动态值。

储蓄(**)

这对我很管用。 如果我们只想在ModelSerializer中添加一个额外的字段,我们可以做到 做它像下面,也字段可以分配一些val后 查找的一些计算。或者在某些情况下,如果我们想发送 参数的API响应。

在model.py

class Foo(models.Model):
    """Model Foo"""
    name = models.CharField(max_length=30, help_text="Customer Name")

在serializer.py

class FooSerializer(serializers.ModelSerializer):
    retrieved_time = serializers.SerializerMethodField()
    
    @classmethod
    def get_retrieved_time(self, object):
        """getter method to add field retrieved_time"""
        return None

  class Meta:
        model = Foo
        fields = ('id', 'name', 'retrieved_time ')

希望这能帮助到一些人。