【问题标题】:Filter Queryset in Wagtail ModelAdmin not workingWagtail ModelAdmin中的过滤查询集不起作用
【发布时间】:2019-10-16 00:11:46
【问题描述】:

我有一个菜单项,其中包含 4 种资源,每种语言,如果用户转到 EnResources,我希望它只显示语言字段包含“en”的资源,并且与其他语言相同。所以问题是它只得到 en 项目,无论我选择哪个菜单项,它总是 en 项目,而不是 FrResources 或任何东西。

我正在关注文档http://docs.wagtail.io/en/v2.5.1/reference/contrib/modeladmin/indexview.html#modeladmin-get-queryset

模型.py

class Resource(models.Model):
    language = models.CharField(max_length=255, choices=constants.LANGUAGES)
    title = models.CharField(blank=True, max_length=255)
    resource_type = models.CharField(
        choices=constants.RESOURCE_TYPES,
        max_length=255
    )
    description =  models.TextField()
    link = StreamField(
        blocks.BasicLinkBlock(max_num=1),
        blank=True,
    )


    panels = [
        FieldPanel('language'),
        FieldPanel('title'),
        FieldPanel('resource_type'),
        FieldPanel('description'),
        StreamFieldPanel('link'),
    ]

常量.py

RESOURCE_TYPES = (
    ('Documentation', 'Documentation'),
    ('Whitepaper', 'Whitepaper'),
    ('Webinar', 'Webinar'),
    ('Video', 'Video'),
    ('Testimonial', 'Testimonial'),
    ('ProductSheet', 'ProductSheet'),
)

LANGUAGES = (
    ('en', 'English'),
    ('fr', 'French'),
    ('be-fr', 'Belgique'),
    ('be-nl', 'Nederlands'),
)

WagtailHooks.py

class ResourceAdmin(ModelAdmin):
    model = models.Resource
    menu_label = 'Resources'
    menu_icon = 'snippet'  # change as required
    list_display = (
        'resource_type',
        'title',
    )
    list_filter = (
        'resource_type',
    )
    search_fields = (
        'title',
        'business_email',
    )

class EnResourceAdmin(ResourceAdmin):
    menu_label = 'English Resources'

    def get_queryset(self, request):

        qs = super().get_queryset(request)
        return qs.filter(language='en')


class FrResourceAdmin(ResourceAdmin):
    menu_label = 'French Resources'

    def get_queryset(self, request):
        qs = super().get_queryset(request)

        return qs.filter(language='fr')


class BeResourceAdmin(ResourceAdmin):
    menu_label = 'Belgium Resources'
    def get_queryset(self, request):
        qs = super().get_queryset(request)

        return qs.filter(language='be-fr')


class NlResourceAdmin(ResourceAdmin):
    menu_label = 'Nederlands Resources'

    def get_queryset(self, request):
        qs = super().get_queryset(request)

        return qs.filter(language='be-nl')


class ResourceAdminGroup(ModelAdminGroup):
    menu_label = 'Resources'
    menu_icon = 'snippet'  # change as required
    menu_order = 1000  # (000 being 1st, 100 2nd)
    items = (
        EnResourceAdmin,
        FrResourceAdmin,
        BeResourceAdmin,
        NlResourceAdmin,
    )

modeladmin_register(ResourceAdminGroup)

编辑: 我开始做更多的研究,我发现根据 default_manager 上的 Django 文档。 https://docs.djangoproject.com/en/2.2/topics/db/managers/#django.db.models.Model._default_manager

如果您使用自定义 Manager 对象,请注意第一个 Manager Django 遇到(按照它们在模型中定义的顺序) 有着特殊的地位。 Django 解释第一个 Manager 中定义的 作为“默认”管理器的类,以及 Django 的几个部分(包括 dumpdata) 将为该模型专门使用该 Manager。作为一个 因此,谨慎选择默认值是个好主意 管理器以避免覆盖 get_queryset() 的情况 导致无法检索您想要使用的对象。

您可以使用指定自定义默认管理器 Meta.default_manager_name。

如果您正在编写一些必须处理未知模型的代码,对于 例如,在实现通用视图的第三方应用程序中,使用此 经理(或 _base_manager),而不是假设模型有 对象管理器。

注意第一段的最后一部分。我认为这正是这里正在发生的事情。

【问题讨论】:

    标签: django wagtail modeladmin


    【解决方案1】:

    这是一个很好的问题,我最近也遇到了类似的问题。 您是正确的,第一个经理将用作默认经理。获得所需结果的一个好方法是为Resource 的每个案例定义proxy models,并为每个代理模型添加custom managers。然后您可以修改get_queryset 以仅返回language = 'some language' 的实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-18
      • 2016-04-13
      • 2022-06-25
      • 2011-10-19
      • 2015-01-05
      • 2014-10-10
      • 2012-11-13
      • 2017-08-06
      相关资源
      最近更新 更多