2014-11-20 68 views
2

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

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 

    ... 

然后在序列化r:

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。必须有一个更清洁的方式来实现这一点?

回答

3

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

啊,我已经想出了第一种方法,但第二种方法更有意义。我错过了[在文档中](http://www.django-rest-framework.org/api-guide/fields#serializermethodfield)。 – 2014-11-20 19:40:35