【问题标题】:DRF: static/read-only/non-model fields in serializers?DRF:序列化程序中的静态/只读/非模型字段?
【发布时间】:2015-08-14 21:00:20
【问题描述】:

是否可以在模型序列化程序中包含静态字段?例如,我有一个模型:

class Location(models.Model):
    long = models.FloatField(...)
    lat = models.FloatField(...)

和一个序列化器:

class LocationSerialiser(serializers.ModelSerializer):
    class Meta:
        model = Location
        fields = ("id", "long", "lat")

用一个简单的ListAPIView 我可以看到我所有的位置:

{
    'id': 1,
    'long': ...,
    'lat': ...,
}, 
...

但是说我想在我的 json 响应中的所有对象中添加一个静态的非模型字段?类似的东西:

{
    'id': 1,
    'long': ...,
    'lat': ...,
    'display': True,
    'icon': 'image/marker.png'
}, 
...

如何将这些添加到序列化程序中?我查看了fields 模块(适用于 2.2.4),但我没有看到任何明确的方法来实现这一点。一切都需要source 属性。

理想情况下我想这样做

class LocationSerialiser(serializers.ModelSerializer):
    display = fields.BooleanField(value=True)
    icon = fields.CharField(value="image/marker.png")

    class Meta:
        model = Location
        fields = ("id", "long", "lat")

编辑

我发现的一种方法是简单地将额外的 @property 包装方法放在模型实例上:

class Location(models.Model):
    long = models.FloatField(...)
    lat = models.FloatField(...)

    @property
    def show(self):
        return True

    ...

然后在序列化器中:

class LocationSerialiser(serializers.ModelSerializer):
    display = fields.BooleanField(value=True)
    icon = fields.CharField(value="image/marker.png")

    show = fields.CharField(source="show")

    class Meta:
        model = Location
        fields = ("id", "long", "lat")

但这似乎很hacky。必须有一种更清洁的方法来实现这一目标吗?

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    如果此字段是模型上的属性或方法(例如 get_full_name),您可以在指向它们的序列化器字段上使用自定义 source。 Django REST Framework 会自动检测它们是方法,并且仍然会调用并显示它们。

    class Location(models.Model):
        # ...
    
        def display(self):
            return True
    
        def icon(self):
            return "image/marker.png"
    
    class LocationSerialiser(serializers.ModelSerializer):
        display = serializers.BooleanField(read_only=True)
        icon = serializers.CharField(read_only=True)
    
        class Meta:
            model = Location
            fields = ("id", "long", "lat", "display", "icon", )
    

    如果您不能或不想将函数放在模型上,Django REST Framework 有 a SerializerMethodField 将调用序列化程序上的方法,该方法可以返回将显示的数据。

    class LocationSerialiser(serializers.ModelSerializer):
        display = serializers.SerializerMethodField("get_display")
        icon = serializers.SerializerMethodField("get_icon")
    
        class Meta:
            model = Location
            fields = ("id", "long", "lat", "display", "icon", )
    
        def get_display(self, obj):
            return True
    
        def get_icon(self, obj):
            return "image/marker.png"
    

    【讨论】:

    • 啊,我已经想出了第一种方法,但第二种方法更有意义。我错过了in the documentation
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多