2017-08-23 28 views
1

我有一個ModelChooserBlock在StreamField中的模型類,如果我打開我的Django Rest框架,我沒有得到滿意的結果。具體來說,「成分」應該有一個鏈接到成分或直接數據庫。Django Rest Framework不顯示來自StreamField的內容

HTTP 200 OK 
Allow: GET, HEAD, OPTIONS 
Content-Type: application/json 
Vary: Accept 

{ 
    "id": 1, 
    "meta": { 
     "type": "cultinadb.Menu", 
     "detail_url": "http://127.0.0.1:8000/api/v2/menu/1/" 
    }, 
    "title": "", 
    "Ingredient": [ 
     { 
      "type": "zutaten", 
      "value": 2, 
      "id": "647d762f-ec26-4c78-928a-446344b1cb8a" 
     }, 
     { 
      "type": "zutaten", 
      "value": 1, 
      "id": "6ab4e425-5e75-4ec0-ba63-8e7899af95e2" 
     } 
    ], 
} 

這裏是我的模型:

from django.db import models 
from wagtail.api import APIField 
from wagtailmodelchooser import register_model_chooser 
from wagtailmodelchooser.blocks import ModelChooserBlock 

@register_model_chooser 
class Ingredient(models.Model): 
    name = models.CharField(max_length=255) 
    picture_url = models.URLField(blank=True) 
    translate_url = models.URLField(blank=True) 

    def __str__(self): 
     return self.name 

@register_model_chooser 
class Menu(models.Model): 
    Ingredient = StreamField([ 
     ('zutaten', ModelChooserBlock('kitchen.Ingredient')) ], 
     null=True, verbose_name='', blank=True) 

    panels = [ 
     MultiFieldPanel(
      [ StreamFieldPanel('Ingredient') ], 
      heading="Zutaten", classname="col5" 
     ), 
    ] 

    def __str__(self): 
     return self.title 

    api_fields = [ 
     APIField('Ingredient'), 
    ] 

I tried to add it as shown here以串行的,但後來我的錯誤。 我創建serializer.py並添加該代碼

class MenuRenditionField(Field): 
    def get_attribute(self, instance): 
     return instance 
    def to_representation(self, menu): 
     return OrderedDict([ 
      ('title', menu.Ingredient.name), 
      ('imageurl', menu.Ingredient.picture_url), 
      ('imageurl', menu.Ingredient.translate_url), 
     ]) 

然後,我改變了我的api_fields這樣

api_fields = [ 
    APIField('Ingredient', serializer=MenuRenditionField()), 
] 

添加此代碼時,我得到的錯誤。

AttributeError at /api/v2/menu/1/ 
'StreamValue' object has no attribute 'name' 
    Request Method: GET 
    Request URL: http://127.0.0.1:8000/api/v2/menu/1/ 
    Django Version: 1.11.1 
    Exception Type: AttributeError 
    Exception Value: 
    'StreamValue' object has no attribute 'name' 

我將非常感謝您的幫助。謝謝!

回答

3

您可以通過覆蓋get_api_representation方法來自定義StreamField塊的API輸出。在這種情況下,它可能看起來像:

class IngredientChooserBlock(ModelChooserBlock): 
    def get_api_representation(self, value, context=None): 
     if value: 
      return { 
       'id': value.id, 
       'name': value.name, 
       # any other relevant fields of your model... 
      } 

然後在您的StreamField定義代替ModelChooserBlock('kitchen.Ingredient')使用IngredientChooserBlock('kitchen.Ingredient')

+0

它的工作原理!非常感謝你! @gasman https://i.stack.imgur.com/dvXVO.png – khashashin

+0

嘿@gasman謝謝你的幫助,其實你爲我做了兩次。 此代碼工作良好,但是對於examle它不能從StreamField表示數據集I具有 '成分= StreamField([ ( 'zutaten',IngredientChooserBlock( 'kitchen.Ingredient'))], 空=真,verbose_name =「」,空=真)' 和它打印出這樣的 \t '類型的對象在DRF錯誤「StreamValue」不是JSON serializable' – khashashin

+0

@khashashin從這個錯誤,它聽起來就像你回來get_api_representation'響應中的某個複雜對象,比如返回value而不是'value.name'等 - DRF只能使用簡單的Python類型,例如字符串,列表和字典。我需要查看完整的代碼才能進一步調查,但我建議將其作爲一個新問題開放。 – gasman