首页 文章

Django REST框架:向ModelSerializer添加其他字段

提问于
浏览
105

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

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 "extra fields can correspond to any property or callable on the model" . 我正在谈论的是额外的领域吗?我应该在_232497的模型定义中定义一个返回 my_field 值的函数,并且在序列化器中我将my_field挂钩到那个可调用的函数吗?那是什么样的?

在此先感谢,如有必要,请尽快澄清问题 .

7 回答

  • 8

    我认为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

  • 176

    正如Chemical Programerthis 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

  • 2

    我对类似问题(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')
    

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

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

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

    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),您不需要更改为属性 . 模型方法将正常工作 .

  • 31

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

    **

    希望这可以帮助别人

    **

  • 11

    使用最新版本的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',)
    
  • 0

    如果你想在额外的字段上读写,你可以使用一个新的自定义序列化器,它扩展了serializers.Serializer,并像这样使用它

    class ExtraFieldSerializer(serializers.Serializer):
        def to_representation(self, instance): # this would have the same as body as in a SerializerMethodField
            return 'my logic here'
        def to_internal_value(self, data):
            return 'Any python object made with data: %s' % data
    
    class MyModelSerializer(serializers.ModelSerializer):
        my_extra_field = ExtraFieldSerializer(source='*')
    
        class Meta:
            model = MyModel
            fields = ['id', 'my_extra_field']
    

    我在相关的嵌套字段中使用它与一些自定义逻辑

相关问题