<p>使用<a href="https://github.com/wagtail/wagtail-generic-chooser" rel="nofollow noreferrer">^{<cd1>}</a>提供了更多定制选择器模式工作方式的能力</p>
<h2>步骤1-安装<code>wagtail-generic-chooser</code></h2>
<ul>
<li>运行:<code>pip install wagtail-generic-chooser</code></li>
<li>然后将<code>generic_chooser</code>添加到项目的<code>INSTALLED_APPS</code></李>
</ul>
<h2>步骤2-设置选择器视图集</h2>
<ul>
<li>类似于<a href="https://github.com/wagtail/wagtail-generic-chooser#chooser-views-model-based" rel="nofollow noreferrer">setting up a Chooser view set</a>上的文档说明</li>
<li>确保我们可以通过创建扩展<code>ModelChooserMixin</code>的自定义类来处理<code>accept</code>参数,这意味着在搜索时仍会传递参数</李>
<li>添加对<code>accept</code>URL参数的处理,以有条件地筛选返回值</李>
<li>设置一个扩展<code>ModelChooserViewSet</code>的类,该类将处理模式中<code>Document</code>列表的显示</李>
</ul>
<h4><strong>基本/视图.py</strong><h4>
<pre class="lang-py prettyprint-override"><code>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"]
</code></pre>
<h2>步骤3-创建选择器小部件</h2>
<ul>
<li>此小部件不是<code>Block</code>,但将用作<code>Block</code>的基础,也可用于<code>FieldPanel</code></李>
<li>与<a href="https://github.com/wagtail/wagtail-generic-chooser#chooser-widgets-model-based" rel="nofollow noreferrer">Setting up of a model based Widget</a>类似,创建一个扩展<code>AdminChooser</code>的类</李>
<li>在<code>__init__</code>方法中,我们拉出<code>accept</code>kwarg,以便使用它生成自定义URL参数</李>
<li>重写<code>get_edit_item_url</code>方法,该方法允许单击所选的</em>文档进行编辑</李>
<li>覆盖“get\u choose\u modal\u url<code>to append the URL query param (note: I could not get</code>reverse`working here而不产生更多的争论)</李>
</ul>
<h4><strong>base/models.py</strong><h4>
<pre class="lang-py prettyprint-override"><code>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])
</code></pre>
<h2>步骤4-在Wagtail钩子中注册选择器视图集</h2>
<ul>
<li>这里不需要使用<code>construct_document_chooser_queryset</code>,而是使用钩子<code>register_admin_viewset</code>并注册<code>RestrictedDocumentChooserViewSet</code></李>
</ul>
<h4><strong>底座/摇尾钩.py</strong><h4>
<pre class="lang-py prettyprint-override"><code>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"
)
</code></pre>
<h2>步骤5-设置并使用自定义<code>Block</code></h2>
<ul>
<li>此类扩展了<code>ChooserBlock</code>并包装了已创建的<code>RestrictedDocumentChooser</code>小部件</李>
<li>在<code>__init__</code>上,相同的kwarg<code>accept</code>被拉出,并在创建时传递给<code>RestrictedDocumentChooser</code></李>
<li>这个块可以通过调用类似于任何其他块的方法来使用,但使用kwarg<code>accept</code><code>doc_block = RestrictedDocumentChooserBlock(accept="svg,md")</code></li>
</ul>
<h4><strong>基本/块.py</strong><h4>
<pre class="lang-py prettyprint-override"><code>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)
</code></pre>