Django+PostgreSQL技术栈下如何实现复选框式产品筛选功能
方案1:使用Django-Filter实现(推荐,自动处理去重、多选项筛选)
适合需要快速添加多维度筛选的场景,无需手动处理参数解析和查询逻辑。
- 新建
filters.py定义筛选规则:
from django import forms import django_filters from .models import Product class ProductFilter(django_filters.FilterSet): # 自动去重获取所有品牌作为复选框选项 brand = django_filters.ModelMultipleChoiceFilter( field_name="brand", queryset=Product.objects.values_list("brand", flat=True).distinct().order_by("brand"), widget=forms.CheckboxSelectMultiple, ) # 可快速扩展其他规格筛选,比如RAM、ROM ram = django_filters.ModelMultipleChoiceFilter( field_name="ram", queryset=Product.objects.values_list("ram", flat=True).distinct().order_by("ram"), widget=forms.CheckboxSelectMultiple, ) rom = django_filters.ModelMultipleChoiceFilter( field_name="rom", queryset=Product.objects.values_list("rom", flat=True).distinct().order_by("rom"), widget=forms.CheckboxSelectMultiple, ) class Meta: model = Product fields = ["brand", "ram", "rom"]
- 修改
views.py逻辑:
from .filters import ProductFilter def product(request): # 先限定分类为手机类 product_queryset = Product.objects.filter(category=1) # 自动处理GET参数完成筛选 product_filter = ProductFilter(request.GET, queryset=product_queryset) return render(request, "list/processor.html", { "filter": product_filter, "proc": product_filter.qs # 筛选后的商品列表 })
- 修改模板
product.html渲染筛选表单和商品列表:
<!-- 筛选表单 --> <form method="get"> <h4>品牌筛选</h4> {% for choice in filter.form.brand.field.choices %} <div class="form-check"> <input class="form-check-input" type="checkbox" name="brand" value="{{ choice.0 }}" id="brand-{{ forloop.counter }}" {% if choice.0 in filter.form.brand.value|default:list %}checked{% endif %}> <label class="form-check-label" for="brand-{{ forloop.counter }}"> {{ choice.1 }} </label> </div> {% endfor %} <h4>RAM筛选</h4> {% for choice in filter.form.ram.field.choices %} <div class="form-check"> <input class="form-check-input" type="checkbox" name="ram" value="{{ choice.0 }}" id="ram-{{ forloop.counter }}" {% if choice.0 in filter.form.ram.value|default:list %}checked{% endif %}> <label class="form-check-label" for="ram-{{ forloop.counter }}"> {{ choice.1 }}G </label> </div> {% endfor %} <button type="submit" class="btn btn-primary mt-3">应用筛选</button> </form> <!-- 筛选后的商品列表 --> <div class="product-list mt-4"> {% for item in proc %} <div class="product-item"> <h5>{{ item.name }}</h5> <p>品牌:{{ item.brand }} | 内存:{{ item.ram }}G/{{ item.rom }}G</p> </div> {% empty %} <p>暂无符合条件的商品</p> {% endfor %} </div>
方案2:原生Django实现(无需第三方依赖)
适合小项目不想引入额外包的场景,手动处理筛选逻辑。
- 修改
views.py:
def product(request): # 自动去重获取所有可选规格 all_brands = Product.objects.values_list("brand", flat=True).distinct().order_by("brand") all_rams = Product.objects.values_list("ram", flat=True).distinct().order_by("ram") # 获取用户选中的参数 selected_brands = request.GET.getlist("brand") selected_rams = request.GET.getlist("ram") # 构造查询逻辑 proc = Product.objects.filter(category=1) if selected_brands: proc = proc.filter(brand__in=selected_brands) if selected_rams: proc = proc.filter(ram__in=selected_rams) return render(request, "list/processor.html", { "proc": proc, "all_brands": all_brands, "all_rams": all_rams, "selected_brands": selected_brands, "selected_rams": selected_rams, })
- 模板渲染逻辑和方案1一致,把
filter.form.xxx.field.choices替换为对应的all_xxx变量即可。
内容的提问来源于stack exchange,提问作者santosh Chauhan
相关产品推荐
相关产品推荐

