如何将页面隐私复制到 Wagtail 中的 Block?
How to copy page-privacy to Block in Wagtail?
页面具有此隐私设置,可以设置允许哪些人查看特定页面。
我的文档需要更精细的杠杆,对于特定的块,还可以设置为限制其可见性。
我对组选择器非常满意,但显然我不能在 Page 模型中放置 ManyToManyRelation。相反,我会在我需要特别处理的块中进行。
所以我尝试像这样定义块:
class MyBlock(StructBlock):
visible_groups = ListBlock(ChooserBlock(
label=_('Limit view to groups'), target_model='django.contrib.auth.groups',
required=False, blank=True
))
但是 Wagtail 抱怨说 ChooserBlock 的声明没有 target_model 属性。我想缺少构造函数就足以表明 ChooserBlock 本身不适用于这样的操作。
我如何正确声明我的块,以便我可以 select 组,然后在渲染时正确识别它们并将它们与用户组匹配?
ChooserBlock
不能单独使用,而是一个基础 class 可以用来构建其他类型的选择器。
选项 0 - 使用相关模型
- 虽然我理解您不想使用模型关系的愿望,但您可能会通过尝试在此处使用 StreamFields 最终造成很多复杂性。
- 可能值得根据基本关系重新考虑问题,您的页面作为内容项列表,每个内容项与授权组具有一对多关系并且具有一些内容(富文本等) .
- 您可以使用与您的页面相关的普通模型来执行此操作,并使用 Wagtail 的 InlinePanel 允许用户创建许多这样的内容项,每个项都有自己的身份验证组集和内容。请记住,其他模型的内部内容仍然可以基于 StreamField,但此方法中的主要连接将是正常的 Django 关系。
- 请记住,StreamField 链接不那么可靠(例如,如果 auth 组被删除,链接可能会在您的 StreamField 中变得陈旧,并且没有简单的方法来阻止它),而且如果您想移动,迁移会变得非常复杂以后身边的事情多一些。
选项 1 - 使用 SnippetChooser
实现此功能的最快方法是使用 SnippetChooserBlock
and register the Django auth groups as a snippet。这种方法的一个警告是模型将在管理员的代码片段菜单(如果启用)中可见 UI。
首先,将模型注册为中心某处的片段(例如wagtail_hooks.py
)
from django.contrib.auth.models import Group
from wagtail.snippets.models import register_snippet
# ... other hooks things
register_snippet(Group)
然后使用 SnippetChooser
构建您的自定义 StructBlock
,无论您在哪里放置积木。
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 的一些快速结果(我没有使用过这些)。
- https://github.com/wagtail/wagtail-generic-chooser
- https://github.com/Naeka/wagtailmodelchooser/
- https://github.com/neon-jungle/wagtailmodelchooser
- https://github.com/springload/wagtailmodelchoosers
请记住,选择器块特定于 StreamField 实现,选择器类似于特定类型的 Django 小部件。如果要为此实现使用 StreamFields,则需要构建或获取两者。
如果您需要构建自己的选择器,我建议您深入了解 Wagtail 的内部结构,了解其他选择器的构建方式。
- 选择器块 - https://github.com/wagtail/wagtail/blob/master/wagtail/core/blocks/field_block.py
- AdminChooser - https://github.com/wagtail/wagtail/blob/master/wagtail/admin/widgets.py
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"
页面具有此隐私设置,可以设置允许哪些人查看特定页面。
我的文档需要更精细的杠杆,对于特定的块,还可以设置为限制其可见性。
我对组选择器非常满意,但显然我不能在 Page 模型中放置 ManyToManyRelation。相反,我会在我需要特别处理的块中进行。
所以我尝试像这样定义块:
class MyBlock(StructBlock):
visible_groups = ListBlock(ChooserBlock(
label=_('Limit view to groups'), target_model='django.contrib.auth.groups',
required=False, blank=True
))
但是 Wagtail 抱怨说 ChooserBlock 的声明没有 target_model 属性。我想缺少构造函数就足以表明 ChooserBlock 本身不适用于这样的操作。
我如何正确声明我的块,以便我可以 select 组,然后在渲染时正确识别它们并将它们与用户组匹配?
ChooserBlock
不能单独使用,而是一个基础 class 可以用来构建其他类型的选择器。
选项 0 - 使用相关模型
- 虽然我理解您不想使用模型关系的愿望,但您可能会通过尝试在此处使用 StreamFields 最终造成很多复杂性。
- 可能值得根据基本关系重新考虑问题,您的页面作为内容项列表,每个内容项与授权组具有一对多关系并且具有一些内容(富文本等) .
- 您可以使用与您的页面相关的普通模型来执行此操作,并使用 Wagtail 的 InlinePanel 允许用户创建许多这样的内容项,每个项都有自己的身份验证组集和内容。请记住,其他模型的内部内容仍然可以基于 StreamField,但此方法中的主要连接将是正常的 Django 关系。
- 请记住,StreamField 链接不那么可靠(例如,如果 auth 组被删除,链接可能会在您的 StreamField 中变得陈旧,并且没有简单的方法来阻止它),而且如果您想移动,迁移会变得非常复杂以后身边的事情多一些。
选项 1 - 使用 SnippetChooser
实现此功能的最快方法是使用 SnippetChooserBlock
and register the Django auth groups as a snippet。这种方法的一个警告是模型将在管理员的代码片段菜单(如果启用)中可见 UI。
首先,将模型注册为中心某处的片段(例如wagtail_hooks.py
)
from django.contrib.auth.models import Group
from wagtail.snippets.models import register_snippet
# ... other hooks things
register_snippet(Group)
然后使用 SnippetChooser
构建您的自定义 StructBlock
,无论您在哪里放置积木。
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 的一些快速结果(我没有使用过这些)。
- https://github.com/wagtail/wagtail-generic-chooser
- https://github.com/Naeka/wagtailmodelchooser/
- https://github.com/neon-jungle/wagtailmodelchooser
- https://github.com/springload/wagtailmodelchoosers
请记住,选择器块特定于 StreamField 实现,选择器类似于特定类型的 Django 小部件。如果要为此实现使用 StreamFields,则需要构建或获取两者。
如果您需要构建自己的选择器,我建议您深入了解 Wagtail 的内部结构,了解其他选择器的构建方式。
- 选择器块 - https://github.com/wagtail/wagtail/blob/master/wagtail/core/blocks/field_block.py
- AdminChooser - https://github.com/wagtail/wagtail/blob/master/wagtail/admin/widgets.py
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"