You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wagtail中如何在ServicePage上通过TariffPagePrices属性筛选ServiceCategoryPage?

问题描述

现有页面层级结构:ServiceCategoryPage → ServicePage → TariffPage,同时存在如下模型代码:

TariffPagePrices(Orderable):
    page = ParentalKey(TariffPage, on_delete=models.CASCADE, related_name='tariff_prices')
    # 示例筛选属性:比如价格、状态等
    ....

需要在ServicePage页面中,根据TariffPagePrices的属性筛选ServiceCategoryPage的结果。

解决方案

要实现这个需求,你可以借助Django/Wagtail的ORM多层关联查询能力,通过反向关联链筛选目标分类页面,以下是具体实现方式:

1. 明确关联逻辑

页面与模型的关联链为:
ServiceCategoryPage → 子页面ServicePage → 子页面TariffPage → 关联模型TariffPagePrices(通过tariff_prices反向关联)

2. 在ServicePage中编写筛选逻辑

假设你要筛选**旗下存在至少一个TariffPage关联的TariffPagePrices满足price < 100**的ServiceCategoryPage,可以在ServicePage模型中重写get_context方法:

from wagtail.models import Page
from django.db.models import Exists, OuterRef

class ServicePage(Page):
    # 你的页面字段定义...

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        
        # 子查询:匹配满足TariffPagePrices条件的TariffPage
        tariff_subquery = TariffPage.objects.filter(
            parent=OuterRef('pk'),
            tariff_prices__price__lt=100  # 替换为你的实际筛选条件
        )
        
        # 筛选包含符合条件ServicePage的ServiceCategoryPage
        filtered_categories = ServiceCategoryPage.objects.filter(
            service_pages__in=ServicePage.objects.filter(Exists(tariff_subquery))
        ).distinct()
        
        context['filtered_categories'] = filtered_categories
        return context

3. 优化反向关联(可选)

如果页面模型没有默认的清晰反向关联名称,可以给页面添加ParentalKey并指定related_name,让查询更直观:

class ServicePage(Page):
    parent_page_types = ['your_app.ServiceCategoryPage']
    subpage_types = ['your_app.TariffPage']
    # 添加到分类页面的反向关联
    category = ParentalKey('your_app.ServiceCategoryPage', on_delete=models.CASCADE, related_name='service_pages')

class TariffPage(Page):
    parent_page_types = ['your_app.ServicePage']
    subpage_types = []
    # 添加到服务页面的反向关联
    service = ParentalKey('your_app.ServicePage', on_delete=models.CASCADE, related_name='tariff_pages')

此时可以简化筛选代码,直接通过多层反向关联查询:

filtered_categories = ServiceCategoryPage.objects.filter(
    service_pages__tariff_pages__tariff_prices__price__lt=100
).distinct()

注意:使用多层关联查询时必须加.distinct(),避免返回重复的分类页面结果。

4. 模板中使用筛选结果

在ServicePage的模板里,直接遍历filtered_categories即可:

{% for category in filtered_categories %}
    <div class="category-item">
        <h3><a href="{{ category.url }}">{{ category.title }}</a></h3>
    </div>
{% endfor %}

内容的提问来源于stack exchange,提问作者IvanSCM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 14:57:23