2014-11-20 67 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