2017-08-23 16 views
1

StreamField内にModelChooserBlockを持つモデルクラスがあります。私がDjango Rest Frameworkを開くと、満足のいく結果が得られません。具体的には、「成分」は成分へのリンクを持っているか、データベースに直接リンクしているはずです。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 = [ 
    APIField('Ingredient', serializer=MenuRenditionField()), 
] 

このコードを追加するとき、私は取得エラーのように私のapi_fieldsを変更しました。

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出力をカスタマイズできます。次に、あなたのStreamField定義でModelChooserBlock('kitchen.Ingredient')の代わりにIngredientChooserBlock('kitchen.Ingredient')を使用

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... 
      } 

:この場合、それはのようになります。

+0

これは機能します。どうもありがとうございました! @gasman https://i.stack.imgur.com/dvXVO.png – khashashin

+0

こんにちは@ガスマンあなたの助けてくれてありがとう、実際には私のためにそれを2回しました。 このコードはうまく機能するが、それは私が '成分= StreamField([ ( 'zutaten'、IngredientChooserBlock( 'kitchen.Ingredient'))]、 ヌル=真、verbose_nameを有するexamleためStreamFieldからデータセットを表すことができません=「」、空白=真) ' 、それはタイプのこの \t 'オブジェクトのようにDRFにエラーを出力「StreamValue」はそのエラーから@khashashin JSONのserializable' – khashashin

+0

ではありませんあなたが戻っているように、それが聞こえます'value_name'の代わりに' value'を返すなど、 'get_api_representation'レスポンスのどこかに複雑なオブジェクトがあります。 - DRFは、文字列、リスト、およびdictsのような単純なPython型でのみ動作します。私はさらに調査するために完全なコードを見る必要があるでしょう - 私は新しい質問として開くことをお勧めします。 – gasman

関連する問題