Using wagtail-generic-chooser提供了更多定制选择器模式工作方式的能力。
第 1 步 - 安装wagtail-generic-chooser
- Run:
pip install wagtail-generic-chooser
- 然后加
generic_chooser
到你的项目的INSTALLED_APPS
.
第 2 步 - 设置选择器视图集
- 类似于文档说明设置选择器视图集
- 确保我们能够处理
accept
参数通过创建扩展的自定义类ModelChooserMixin
,这意味着搜索时参数仍然会被传递。
- 添加处理
accept
有条件地过滤返回值的 URL 参数。
- 设置一个扩展类
ModelChooserViewSet
这将处理的显示Document
在模式中列出。
基础/views.py
from django.db.models import Q
from generic_chooser.views import ModelChooserMixin, ModelChooserViewSet
from wagtail.documents.models import Document
class RestrictedDocumentChooserMixin(ModelChooserMixin):
# preserve this URL parameter on pagination / search
preserve_url_parameters = [
"accept",
]
def get_unfiltered_object_list(self):
objects = super().get_unfiltered_object_list()
accept = self.request.GET.get("accept")
print("get_unfiltered_object_list", accept)
if accept:
accepted_files = accept.split(",")
queries = [Q(file__iendswith=f".{value}") for value in accepted_files]
query = queries.pop()
for item in queries:
query |= item
objects = objects.filter(query)
return objects
class RestrictedDocumentChooserViewSet(ModelChooserViewSet):
chooser_mixin_class = RestrictedDocumentChooserMixin
icon = "doc"
model = Document
page_title = "Choose a document"
per_page = 10
order_by = "title"
fields = ["title", "file"]
第 3 步 - 创建选择器小部件
- 这个小部件不是
Block
但将用作基础Block
也可用于FieldPanel
.
- 类似于设置基于模型的 Widget创建一个类来扩展
AdminChooser
.
- In the
__init__
方法我们拉出accept
kwarg,因此我们可以使用它来生成自定义 URL 参数。
- 覆盖
get_edit_item_url
方法将允许点击selected编辑它的文档。
- 覆盖``get_choose_modal_url
to append the URL query param (note: I could not get
在这里工作,没有更多的争论)。
基础/模型.py
from django.contrib.admin.utils import quote
from django.urls import reverse
from generic_chooser.widgets import AdminChooser
from wagtail.documents.models import Document
class RestrictedDocumentChooser(AdminChooser):
def __init__(self, **kwargs):
self.accept = kwargs.pop("accept")
super().__init__(**kwargs)
choose_one_text = "Choose a Document"
choose_another_text = "Choose another document"
link_to_chosen_text = "Edit this document"
model = Document
choose_modal_url_name = "restricted_document_chooser:choose"
def get_choose_modal_url(self):
url = super().get_choose_modal_url()
return url + "?accept=%s" % self.accept
def get_edit_item_url(self, item):
return reverse("wagtaildocs:edit", args=[item.id])
第 4 步 - 在 Wagtail Hooks 中注册选择器视图集
- 无需使用
construct_document_chooser_queryset
在这里,改为使用钩子register_admin_viewset
并注册RestrictedDocumentChooserViewSet
.
基地/wagtail_hooks.py
from wagtail.core import hooks
from .views import RestrictedDocumentChooserViewSet
# ... other hooks etc
@hooks.register("register_admin_viewset")
def register_restricted_document_chooser_viewset():
return RestrictedDocumentChooserViewSet(
"restricted_document_chooser", url_prefix="restricted-document-chooser"
)
第 5 步 - 设置并使用自定义Block
- 这个类扩展了
ChooserBlock
并包裹RestrictedDocumentChooser
已创建的小部件。
- On
__init__
同一个夸格accept
被拉出并传递给RestrictedDocumentChooser
创建时。
- 该块可以通过与任何其他块类似的方式调用它来使用,使用 kwarg
accept
尽管。doc_block = RestrictedDocumentChooserBlock(accept="svg,md")
基础/块.py
from django.utils.functional import cached_property
from wagtail.images.blocks import ChooserBlock
# ...
class RestrictedDocumentChooserBlock(ChooserBlock):
def __init__(self, **kwargs):
self.accept = kwargs.pop("accept")
super().__init__(**kwargs)
@cached_property
def target_model(self):
from wagtail.documents.models import Document
return Document
@cached_property
def widget(self):
from .widgets import RestrictedDocumentChooser
return RestrictedDocumentChooser(accept=self.accept)
def get_form_state(self, value):
return self.widget.get_value_data(value)