【问题标题】:Django rest framework - set default serializer for a classDjango rest 框架 - 为类设置默认序列化程序
【发布时间】:2021-03-27 10:33:21
【问题描述】:

在我的代码中,我有几个具有多个自定义属性的模型:

@dataclass
class Value:
    amount: float
    currency: str

class MyModel(models.Model):
    ...
    
    @property
    def v1(self) -> Value:
        ...
    
    @property
    def v2(self) -> Value:
        ...
    
    @property
    def v3(self) -> Value:
        ...

我有以下序列化程序:

class MyModelBaseSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = [..., "v1", "v2", "v3"]

当序列化任何 MyModel 实例时,会引发 TypeError:TypeError: Object of type Value is not JSON serializable

我知道这可以通过在MyModelBaseSerializer 中显式添加v1, v2, v3 作为字段来解决,但我不想这样做:我有很多具有Value 属性的模型。我希望默认 DRF 序列化程序知道如何序列化 Value 实例。

我尝试覆盖to_representation,但这似乎不起作用。
我想要类似于覆盖 JSONEncoder.default(o) 方法的东西,但我不知道如何告诉 DRF 使用哪个编码器。

【问题讨论】:

    标签: python json django serialization django-rest-framework


    【解决方案1】:

    Value 添加一个自定义序列化程序。例如(未测试)。

    class ValueSerializer(serializers.Serializer):
        amount = serializers.FloatField()
        currency = serializers.CharField()
    
    
    class MyModelBaseSerializer(serializers.ModelSerializer):
        v1 = ValueSerializer()
        v2 = ValueSerializer()
        v3 = ValueSerializer()
        ...
    

    或者,由于Valuedataclass,请查看https://github.com/oxan/djangorestframework-dataclasses

    编辑

    一种快速而肮脏的 DRY 方法是覆盖序列化程序上的 build_property_field (see docs)。

    class MyModelBaseSerializer(serializers.ModelSerializer):
        def build_property_field(self, field_name, model_class):
            if field_name in ["v1", "v2", "v3"]:
                return ValueSerializer, {}
            return super().build_property_field(field_name, model_class)
    

    覆盖serializer_field_mapping 是另一种选择。

    【讨论】:

    • 感谢您的回答。正如我所写,我不想显式添加所有字段(我有多个这样的模型)。无论如何,这似乎是一个反 DRY 解决方案(尽管这就是我现在所做的)。
    猜你喜欢
    • 1970-01-01
    • 2020-09-14
    • 2017-10-03
    • 2019-05-20
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    相关资源
    最近更新 更多