求助:基于Django通用ListView实现多条件商品搜索功能
Django ListView 实现多条件商品筛选修复方案
先梳理原代码中的问题:
- models.py 存在导入错误、验证器类名错误及实例化问题
- views.py 中
get_context_data方法有语法错误,get_queryset未处理表单无效的边界情况 - 视图指定的模板文件名与实际模板文件名不匹配
以下是修正后的完整代码:
models.py
from django.db import models from django.core.validators import RegexValidator class Product(models.Model): num = RegexValidator(r'^[0-9a-zA-Z]*$') title = models.CharField(max_length=100) embed_id = models.CharField(max_length=15, validators=[num]) description = models.TextField(null=True, blank=True)
forms.py
from django import forms class ProductSearchForm(forms.Form): title = forms.CharField(required=False, label="商品标题") embed_id = forms.CharField(required=False, label="嵌入ID") description = forms.CharField(required=False, label="商品描述", widget=forms.Textarea(attrs={'rows':3}))
(给字段添加label和优化描述输入框,提升用户体验,可按需保留)
views.py
from django.views.generic import ListView from .models import Product from .forms import ProductSearchForm class ProductListView(ListView): model = Product form_class = ProductSearchForm template_name = 'pages/product/list_products.html' # 和实际模板文件名保持一致,若模板是product_search.html则修改此处 def get_queryset(self): queryset = super().get_queryset() form = self.form_class(self.request.GET) if form.is_valid(): title = form.cleaned_data.get('title') embed_id = form.cleaned_data.get('embed_id') description = form.cleaned_data.get('description') if title: queryset = queryset.filter(title__icontains=title) if embed_id: queryset = queryset.filter(embed_id__icontains=embed_id) if description: queryset = queryset.filter(description__icontains=description) # 表单无效时返回原始查询集 return queryset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 传入已绑定数据的表单,保留用户输入内容 context['form'] = self.form_class(self.request.GET) return context
模板文件(list_products.html)
<form method="get" action="{% url 'product_list' %}"> {{ form.as_p }} <input type="submit" value="搜索"> </form> {% if object_list %} <ul> {% for product in object_list %} <li>{{ product.title }} - {{ product.embed_id }}</li> {% endfor %} </ul> {% else %} <p>未找到匹配的商品</p> {% endif %}
注意事项
- 确保URL配置中
product_list路由对应到ProductListView - 若使用
product_search.html作为模板文件名,需同步修改视图中的template_name参数 - 筛选逻辑用
__icontains实现模糊匹配,若需精确匹配可改为filter(title=title)这类写法
内容的提问来源于stack exchange,提问作者Mehdi
相关产品推荐
相关产品推荐

