ChooserBlock
并不是要单独使用,而是要用于构建其他类型的选择器的基类。
选项 0 - 使用相关模型
- 虽然我理解您不想使用模型关系的愿望,但您最终可能会通过尝试在此处使用 StreamFields 来创建很多复杂性。
- 在基本关系方面重新考虑问题可能是值得的,您的页面作为内容项列表,每个内容项与身份验证组具有一对多的关系并且具有一些内容(富文本等)。
- 您可以使用与您的页面相关的普通模型来执行此操作,并使用 Wagtail 的InlinePanel允许用户创建许多这些内容项,每个内容项都有自己的身份验证组集和内容。请记住,其他模型上的内部内容仍然可以基于 StreamField,但此方法中的主要连接将是正常的 Django 关系。
- 请记住,StreamField 链接不是那么健壮(例如,如果 auth 组被删除,链接可能会在您的 StreamField 中变得陈旧,并且没有简单的方法来阻止它),如果您想在未来。
选项 1 - 使用SnippetChooser
最快的方法是使用SnippetChooserBlock
Django auth 组并将其注册为一个片段。这种方法的一个警告是,该模型将在管理 UI 的片段菜单(如果启用)中可见。
首先,将模型注册为中央某处的片段(例如wagtail_hooks.py
)
from django.contrib.auth.models import Group
from wagtail.snippets.models import register_snippet
# ... other hooks things
register_snippet(Group)
StructBlock
然后使用SnippetChooser
您保存 Blocks 的任何位置构建您的自定义。
from django.contrib.auth.models import Group
from wagtail.snippets.blocks import SnippetChooserBlock
from wagtail.core.blocks import ListBlock
class PrivacyBlock(StructBlock):
visible_groups = ListBlock(
SnippetChooserBlock(
Group,
label='Limit view to groups',
required=False,
blank=True
)
)
class Meta:
icon = "user"
最后,您可以像任何其他 StructBlock 一样在 PageModel 中使用它。
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel, StreamFieldPanel
from wagtail.core.fields import StreamField
from myapp.blocks import PrivacyBlock
class BlogPage(Page):
# ... other fields
privacy_content = StreamField([
('privacy', PrivacyBlock(blank=True))
])
content_panels = Page.content_panels + [
# ... other panels
StreamFieldPanel('privacy_content'),
]
选项 2 - 构建或使用通用模型选择
您可以扩展 ChooserBlock 以构建您自己的选择器,但这会很快变得复杂,因为您还需要构建自定义模型选择器。下面的代码功能不完整,但可以让您了解可能需要什么。
如果您可以使用其他库,则可能值得考虑添加 Wagtail 通用选择器,这是来自 Google 的一些快速结果(我没有使用这些)。
请记住,选择器块特定于 StreamField 实现,并且选择器类似于特定类型的 Django 小部件。如果您想为此实现使用 StreamFields,您将需要构建或获取两者。
如果您需要构建自己的,我建议您深入了解 Wagtail 的内部结构,以了解其他选择器是如何构建的。
POC(非功能性)代码示例
from wagtail.admin.widgets import AdminChooser
from django.utils.functional import cached_property
class ModelChooser(AdminChooser):
# ... implement __init__ etc
class AuthGroupBlock(ChooserBlock):
@cached_property
def target_model(self):
from django.contrib.auth.models import Group
return Group
@cached_property
def widget(self):
return ModelChooser(self.target_model)
class PrivacyBlock(StructBlock):
visible_groups = ListBlock(
AuthGroupBlock(
label='Limit view to groups',
required=False,
blank=True
)
)
class Meta:
icon = "user"
class PrivacyBlock(StructBlock):
visible_groups = ListBlock(
SnippetChooserBlock(
Group,
label='Limit view to groups',
required=False,
blank=True
)
)
class Meta:
icon = "user"