【问题标题】:Django Rest Framework does not show content from StreamFieldDjango Rest Framework 不显示来自 StreamField 的内容
【发布时间】:2017-08-23 15:02:48
【问题描述】:

我在 StreamField 中有一个带有 ModelChooserBlock 的模型类,如果我打开我的 Django Rest Framework,我不会得到令人满意的结果。具体来说,“成分”应具有指向成分或直接数据库的链接。

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'

我将非常感谢您的帮助。谢谢!

【问题讨论】:

    标签: django wagtail django-rest-framework


    【解决方案1】:

    您可以通过重写 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 定义中使用 IngredientChooserBlock('kitchen.Ingredient') 代替 ModelChooserBlock('kitchen.Ingredient')

    【讨论】:

    • 有效!!非常感谢你! @gasman i.stack.imgur.com/dvXVO.png
    • 嘿@gasman 谢谢你的帮助,实际上你为我做了两次。此代码运行良好,但它不能代表来自 StreamField 的数据集,例如我有 ingredient = StreamField([ ('zutaten', IngredientChooserBlock('kitchen.Ingredient')) ], null=True, verbose_name='', blank=True) 并且它在 DRF 中打印出一个错误,例如 Object of type 'StreamValue' is not JSON serializable
    • @khashashin 从那个错误来看,听起来您在 get_api_representation 响应中的某处返回了一个复杂对象,例如返回 value 而不是 value.name 等 - DRF 只能与简单的 Python 类型,例如字符串、列表和字典。不过,我需要查看完整的代码才能进一步调查 - 我建议作为一个新问题打开。
    • 感谢@gasman 我创建了一个新主题link
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 2018-02-16
    相关资源
    最近更新 更多