如何将 Wagtail 图像选择器面板限制为 collection

How do you restrict a Wagtail image chooser panel to a collection

我在名为 profile_images 的模型中有一个字段,如何将图像选择器面板中显示的图像限制为个人资料图像 collection?

我也想对画廊的内联面板做同样的事情 collection。

这意味着我无法使用权​​限,因为用户应该可以访问这两个 collection。

感谢帮助

Wagtail 有一个名为 hooks 的功能,可以让您修改 Wagtail 的一些内部逻辑,这是一个非常有用的功能,可以让您做到这一点。

有一个钩子叫做 construct_image_chooser_queryset。您需要在您的应用程序文件夹之一中创建一个文件 wagtail_hooks.py,当应用程序 运行s.

时,Wagtail 会获取该文件 运行

一旦有了钩子 运行ning,您就可以为图像选择器模式注入 images 结果的自定义过滤。此挂钩将 运行 用于整个 Wagtail 的各种图像列表,因此您需要添加一些逻辑以确保您不会在所有地方过滤图像。

一种可能的方法是读取传递到挂钩中的请求,以确定当前请求是否用于页面编辑场景。一旦你知道这一点,你就可以计算出正在使用哪个页面 class,然后根据页面 class.

上的一些 class 方法过滤你的图像

当请求图像选择器模式时,您可以阅读 HTTP_REFERRER and from that URL use Django's resolve 以确定调用它的位置以及正在编辑哪个页面。

例子

  • 使用上面描述的钩子,我们读取 HTTP_REFERRER
  • 使用 urlparseresolve 来 return Django match 对象
  • 读取匹配数据以确认我们正在编辑页面
  • 如果编辑页面,我们查询 Page 并使用 specific_class property
  • 最后,我们可以从class中获取一个collection id来过滤图片
  • 注意:如何获取集合 ID 100% 取决于您,您可以对其进行硬编码,使其成为一个单独的函数,甚至使其成为一个特定的 class 方法,但要小心确保如果该方法不适用于所有页面,它都可以工作。
  • 在其他图像选择器中测试这个以确保没有其他问题。
  • 这不会 'hide' 图像选择器模态上的集合下拉列表,不幸的是,您可能只需要使用 CSS 或 JS 来完成此操作。
wagtail_hooks.py
from django.urls import resolve
from urllib.parse import urlparse
from wagtail.core import hooks
from wagtail.core.models import Page


@hooks.register('construct_image_chooser_queryset')
def show_images_for_specific_collections_on_page_editing(images, request):

    # first - pull out the referrer for this current AJAX call
    http_referrer = request.META.get('HTTP_REFERER', None) or '/'

    # second - use django utils to find the matched view
    match = resolve(urlparse(http_referrer)[2])

    # if we are editing a page we can restrict the available images
    if (match.app_name is 'wagtailadmin_pages') and (match.url_name is 'edit'):
        page = Page.objects.get(pk=match.args[0])

        # important: wrap in a try/except as this may not be implemented on all pages
        image_collection_id = page.specific_class.get_image_collection()

        # return filtered images
        return images.filter(collection=image_collection_id)

    return images
models.py
from wagtail.core.models import Page


class BlogPage(Page):
    # ...

    @classmethod
    def get_image_collection(cls):
        # any logic here to determine what collection to filter by
        return 4