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

按品类筛选商品时获取无重复颜色选项(Django实现)

解决Django电商品类下颜色选项去重问题

核心思路:通过QuerySet提前去重,避免模板层被动处理

不用依赖模板里的{% ifchanged %}(它只能处理相邻重复),直接在视图层通过数据库查询拿到无重复的颜色集合,再传给模板渲染即可。


步骤1:根据模型关联编写过滤QuerySet

先明确你的模型关联逻辑,假设基础模型结构如下(如果和实际有出入,调整过滤路径即可):

  • Category ← 一对多 → Product(Product含category外键)
  • Product ← 一对多 → ProductVariant(ProductVariant含product外键)
  • ProductVariant ← 外键 → Colour(ProductVariant含colour外键指向Colour)

在视图函数中,先获取当前品类,再通过反向关联过滤出该品类下所有商品对应的颜色,最后用distinct()去重:

from django.shortcuts import get_object_or_404, render
from .models import Category, Colour

def category_product_list(request, slug):
    # 获取当前筛选的品类
    current_category = get_object_or_404(Category, slug=slug)
    
    # 过滤当前品类下所有商品关联的颜色并去重
    # 注意:过滤路径需和你的模型字段/关联名对应
    unique_colours = Colour.objects.filter(
        productvariant__product__category=current_category
    ).distinct()
    
    # 若仅需颜色名称(而非完整Colour对象),可用values_list优化查询
    # unique_colour_names = Colour.objects.filter(
    #     productvariant__product__category=current_category
    # ).values_list('name', flat=True).distinct()
    
    return render(request, 'shop/category_list.html', {
        'current_category': current_category,
        'unique_colours': unique_colours,
        # 'unique_colour_names': unique_colour_names,
    })

步骤2:模板直接渲染去重后的颜色集合

拿到去重后的QuerySet后,模板里直接循环即可,无需再处理重复:

<!-- 侧边栏颜色筛选模块 -->
<div class="sidebar-filter">
    <h4>颜色</h4>
    <ul class="colour-options">
        {% for colour in unique_colours %}
            <li>
                <label>
                    <input type="checkbox" name="colour" value="{{ colour.slug }}">
                    <span style="color: {{ colour.hex_code }}">{{ colour.name }}</span>
                </label>
            </li>
        {% empty %}
            <li>暂无可选颜色</li>
        {% endfor %}
    </ul>
</div>

注意事项

  • 如果ProductVariant和Colour是多对多关联,只需调整过滤路径:比如Colour.objects.filter(productvariants__product__category=current_category).distinct()(productvariants为多对多字段的related_name)。
  • 若使用SQLite数据库,直接对完整Colour对象用distinct()无效时,可指定去重字段,比如distinct('id', 'name')。
  • 用values_list()配合distinct()能减少数据库返回的数据量,适合仅需颜色名称/标识的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:01:47