django之DRF : static/read-only/non-model fields in serializers

jpfss 阅读:41 2025-02-15 21:57:57 评论:0

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

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。必须有一种更清洁的方法来实现这一目标吗?

请您参考如下方法:

如果此字段是模型上的属性或方法(例如 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" 


标签:Django
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号