【问题标题】:Converting class object to readable value for get_api_representation function将类对象转换为 get_api_representation 函数的可读值
【发布时间】:2018-02-06 15:51:15
【问题描述】:

Previous topic where I was kindly helped by @gasman 所以我有一个模型类成分,例如:

@register_model_chooser
class Ingredient(models.Model):
    name = models.CharField(max_length=255)
    def __str__(self):
        return self.name

为了在 API 中表示这一点,我创建了这个类:

class IngredientChooserBlock(ModelChooserBlock):
    def get_api_representation(self, value, context=None):
        if value:
            return {
                'name': value.name,
            }

然后我有另一个使用IngredientChooserBlock 类的模型类:

@register_model_chooser
class Menu(models.Model):
    ingredient = StreamField([
        ('zutaten', IngredientChooserBlock('kitchen.Ingredient')) ],
        null=True, verbose_name='', blank=True)
        def __str__(self):
            return self.title

因为我在我的 API 中需要这个 ingredient,所以我创建了相同的模型类来覆盖 get_api_representation

class WeekChooserBlock(ModelChooserBlock):
    def get_api_representation(self, value, context=None):
        if value:
            return {
                'ingredients': value.ingredient,
            }

最后在我的主模型类中,我尝试使用这个WeekChooserBlock,它以kitchen.Menu 作为参数,如下所示:

class Week(models.Model):
    dishes_sp = StreamField([
        ('menu', WeekChooserBlock('kitchen.Menu')) ],
        null=True, verbose_name='', blank=True)

问题是它在 DRF 中打印出如下错误:

Object of type 'StreamValue' is not JSON serializable


不想提出太大的问题,但为了更清楚起见,我的 Menu 类中实际上还有另一个对象,例如:

class Menu(models.Model):
    title = models.CharField(max_length=255)
    image = models.URLField(blank=True, null=True)
    price = models.FloatField(blank=True, null=True, max_length=255)
    ingredient = StreamField([
        ('zutaten', IngredientChooserBlock('kitchen.Ingredient')) ],
        null=True, verbose_name='', blank=True)
    steps = StreamField([
        ('Schritt', TextBlock())
        ], null=True, verbose_name='Vorbereitungsschritte', blank=True)

我也试图代表他们。但是只有当我尝试输出StreamField时才会显示错误

class WeekChooserBlock(ModelChooserBlock):
    def get_api_representation(self, value, context=None):
        if value:
            return {
                'title': value.title,
                'picture': value.image,
                'price': value.price,
                'ingredients': value.ingredient,
                'steps': value.steps
            }

感谢您的支持!

【问题讨论】:

    标签: django wagtail django-rest-framework wagtail-streamfield


    【解决方案1】:

    这里的问题是您从WeekChooserBlock.get_api_representation 返回{'ingredients': value.ingredient}。这里value.ingredient 是一个 StreamValue 实例,它是一个复杂的 Wagtail 特定对象,包含用于模板渲染的方法以及实际的流数据 - DRF 不知道如何处理这个复杂的对象。

    您需要确保您的 get_api_representation 响应仅包含标准 Python 类型,例如字符串和字典。例如:

    class WeekChooserBlock(ModelChooserBlock):
        def get_api_representation(self, value, context=None):
            if value:
                return {
                    'ingredients': [ingredient.value['name'] for ingredient in value.ingredient],
                }
    

    如果您想重新使用您在 IngredientChooserBlock.get_api_representation 中定义的成分的 API 表示,它会有点棘手,但您应该能够做到这一点:

    class WeekChooserBlock(ModelChooserBlock):
        def get_api_representation(self, value, context=None):
            if value:
                ingredient = value.ingredient
                return ingredient.stream_block.get_api_representation(ingredient, context=context)
    

    【讨论】:

    • 我尝试使用您提供的代码,但仍然产生错误。您忘记在 value.stream_block 之间插入模型类对象 enyway 我得到错误:return value.stream_block.get_api_representation(value,context=context) 或:return value.ingredient.stream_block.get_api_representation(value,context=context) --- 'Menu' object is not iterable 如果我试图在没有 ingredient 的情况下返回这个我得到:'Menu' object has no attribute 'stream_block'
    • 所以对于其他用户,我尝试了技巧的第二部分 class WeekChooserBlock(ModelChooserBlock): def get_api_representation(self, value, context=None): if value: ingredient = value.ingredient return ingredient.stream_block.get_api_representation(ingredient, context=context) 及其对我的工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多