Django REST Framework:向ModelSerializer添加其他字段

时间:2013-08-23 06:47:17

标签: django rest django-rest-framework

我想序列化一个模型,但是想要包含一个额外的字段,该字段需要对要序列化的模型实例进行一些数据库查找:

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

这样做的正确方法是什么?我看到序列化程序的you can pass in extra "context"是传递上下文字典中附加字段的正确答案吗?使用这种方法,获得我需要的字段的逻辑不会与串行器定义一起自包含,这是理想的,因为每个序列化实例都需要my_field。在DRF序列化器文档的其他地方,says“额外字段可以对应于模型上的任何属性或可调用”。我正在谈论的是额外的领域吗?我应该在Foo的模型定义中定义一个返回my_field值的函数,并且在序列化器中我将my_field挂钩到那个可调用的?那是什么样的?

提前致谢,如有必要,请尽快澄清问题。

7 个答案:

答案 0 :(得分:186)

我认为您正在寻找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

答案 1 :(得分:34)

您可以将模型方法更改为属性,并使用此方法在序列化程序中使用它。

class Foo(models.Model):
    . . .
    @property
    def my_field(self):
        return stuff
    . . .

class FooSerializer(ModelSerializer):
    my_field = serializers.ReadOnlyField(source='my_field')

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

编辑:使用最新版本的rest框架(我尝试过3.3.3),您无需更改为属性。模型方法可以正常工作。

答案 2 :(得分:12)

使用Django Rest Framework的最新版本,您需要在模型中创建一个方法,其中包含您要添加的字段的名称。无需@propertysource='field'引发错误。

class Foo(models.Model):
    . . .
    def foo(self):
        return 'stuff'
    . . .

class FooSerializer(ModelSerializer):
    foo = serializers.ReadOnlyField()

    class Meta:
        model = Foo
        fields = ('foo',)

答案 3 :(得分:8)

我对类似问题(here)的回答可能有用。

如果您有以下列方式定义的模型方法:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

您可以将调用所述方法的结果添加到序列化程序中,如下所示:

class MyModelSerializer(serializers.ModelSerializer):
    model_method_field = serializers.CharField(source='model_method')

P.S。由于自定义字段实际上不是模型中的字段,因此您通常希望将其设置为只读,如下所示:

class Meta:
    model = MyModel
    read_only_fields = (
        'model_method_field',
        )

答案 4 :(得分:1)

  

这对我有用   如果我们只想在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 ')

**

  

希望这可以帮助某人

**

答案 5 :(得分:0)

正如Chemical Programer this comment所述,在最新的DRF中你可以这样做:

class FooSerializer(serializers.ModelSerializer):
    extra_field = serializers.SerializerMethodField()

    def get_extra_field(self, foo_instance):
        return foo_instance.a + foo_instance.b

    class Meta:
        model = Foo
        fields = ('extra_field', ...)

DRF docs source

答案 6 :(得分:0)

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')