【问题标题】:Wagtail/Django: Is it possible to populate a given admin fields options out of the results of an API?Wagtail/Django:是否可以从 API 的结果中填充给定的管理字段选项?
【发布时间】:2021-01-30 23:24:46
【问题描述】:

我正在开发一个 Django 项目,特别是 Wagtail 项目。我想切换下面的代码,以包含一个预填充的管理字段,该字段将由 API 响应填充。这是我目前使用的代码:

"""Flexible page."""
from django.db import models

from wagtail.admin.edit_handlers import FieldPanel
from wagtail.core.models import Page
from wagtail.core.fields import RichTextField
from wagtail.images.edit_handlers import ImageChooserPanel

class FlexPage(Page):
    """Flexibile page class."""

    template = "flex/flex_page.html"

    # @todo add streamfields 
    # content = StreamField()

    subtitle = models.CharField(max_length=100, null=True, blank=True)
    Flexbody = RichTextField(blank=True)
    bannerImage = models.ForeignKey(
        "wagtailimages.Image",
        null=True, 
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+"
    )
    audioUrl = models.URLField()
    content_panels = Page.content_panels + [
        FieldPanel("subtitle"),
        FieldPanel('Flexbody', classname="full"),
        ImageChooserPanel('bannerImage'),
        FieldPanel('audioUrl'),
    ]

    class Meta:  # noqa 
        verbose_name = "Flex Page"
        verbose_name_plural = "Flex Pages"

这将使我能够创建一个标准的 Wagtail URL 字段,并且我可以设置一个指向 MP3 文件的 URL。我想做的是从 API 响应中预填充一个下拉菜单,如下所示:

   {
     "id":"83ee98f6-3207-4130-9508-8f4d15ed7d5c",
     "title":"some random description",
     "description":"some random description.",
     "audio":"https://somerandomurl.mp3",
     "slug":"some random description",
     "draft":false
  },
   {
     "id":"83ee98f6-3207-4130-9508-8f4d15ed7d5c2",
     "title":"some random description2",
     "description":"some random description2.",
     "audio":"https://somerandomurl2.mp3",
     "slug":"some random description2",
     "draft":false2
  },

我想知道如何使用 JSON 响应中的 URL 填充管理字段?我猜 A)这是可能的,B)我将如何编写一个类模型来完成这样的事情?

【问题讨论】:

    标签: django wagtail


    【解决方案1】:

    您可以通过设置a custom form class to be used on the edit view 并将audioUrl 的表单字段设置为ChoiceField 来做到这一点。 ChoiceField 最常用于作为choices 参数的静态选项列表,但它也允许您指定一个返回选项的可调用对象——这将是执行 API 获取的合适位置。代码看起来像这样:

    from django import forms
    from wagtail.admin.forms import WagtailAdminPageForm
    
    def get_mp3_choices():
        # API response is hard-coded here, but you would fetch and parse the JSON instead
        files = [
            {
                "id":"83ee98f6-3207-4130-9508-8f4d15ed7d5c",
                "title":"some random description",
                "description":"some random description.",
                "audio":"https://somerandomurl.mp3",
                "slug":"some random description",
                "draft":False
            },
            {
                "id":"83ee98f6-3207-4130-9508-8f4d15ed7d5c2",
                "title":"some random description2",
                "description":"some random description2.",
                "audio":"https://somerandomurl2.mp3",
                "slug":"some random description2",
                "draft":False
            },
        ]
    
        # return a list of tuples where the first item is the value to store,
        # and the second item is the human-readable label
        return [
            (file['audio'], file['title'])
            for file in files
        ]
    
    class FlexPageForm(WagtailAdminPageForm):
        audioUrl = forms.ChoiceField(choices=get_mp3_choices)
    
    class FlexPage(Page):
        # ...
        base_form_class = FlexPageForm
    

    【讨论】:

    • 我收到以下错误“ValueError: too many values to unpack (expected 2)”,并且文档似乎说明它需要两个选择,我的结果列表中有一些内容20 个结果的范围。
    • "expected 2 values" 不是指结果的数量——它意味着每个结果都需要作为一对值返回——保存的值和人类可读的标签,如我的示例代码。
    • 以上是正确答案,但我想知道您是否介意在其中展示如何在菜单本身上方添加标题。我在页面上有它,但它与周围的元素没有任何分离。
    猜你喜欢
    • 2017-06-03
    • 2020-01-08
    • 2013-06-22
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多