Django实现多字段(地点/价格)产品过滤功能的技术求助
Django实现多字段(地点/价格)产品过滤功能的技术求助
兄弟,我仔细看了你的代码,发现你现在只是把过滤表单渲染出来了,但完全没处理核心的过滤逻辑,还有几个小问题需要先调整,咱们一步步来搞定这个功能:
首先,清理不必要的代码
你定义的ProductFilter模型其实完全没必要,过滤条件是用户临时选择的,不需要保存到数据库里,直接删掉这个模型就行。
然后修正你的表单
你的ProductFilterForm是普通的forms.Form,不需要加Meta类(那是ModelForm专属的配置),调整后的表单代码如下:
place_choices = ( ("A", "All"), ("C", "Cellphones"), ("M", "Media Mart"), ("N", "Nguyễn Kim") ) price_choices = ( ("", "All"), ("A", "Giá thấp > cao"), ("B", "Giá cao > thấp") ) class ProductFilterForm(forms.Form): place = forms.ChoiceField(choices=place_choices, widget=forms.Select()) price = forms.ChoiceField(choices=price_choices, widget=forms.Select())
重点完善视图的过滤逻辑
这里建议用GET请求处理过滤(这样过滤参数会留在URL里,用户刷新页面或分享链接时,过滤条件不会丢失),然后根据获取到的参数逐步筛选产品查询集:
def show_db(request): # 初始化表单,传入GET参数,这样提交后表单会保留用户选中的选项 filterForm = ProductFilterForm(request.GET) # 先获取所有产品的基础查询集 product_list = Product.objects.all() # 提取过滤参数,设置默认值避免报错 ft_place = request.GET.get('place', 'A') ft_price = request.GET.get('price', '') # 处理地点过滤:如果不是选的"All",就按地点筛选 if ft_place != 'A': # 注意这里要对应你Product模型里的地点字段名,假设是`place` product_list = product_list.filter(place=ft_place) # 处理价格排序:根据选项对价格字段升序/降序排列 if ft_price == 'A': # 假设Product模型里的价格字段是`current_price`(数字类型) product_list = product_list.order_by('current_price') elif ft_price == 'B': product_list = product_list.order_by('-current_price') # 保留你原来的其他表单 place = ProductPlaceForm() newForm = ProductNameForm() return render(request, 'product_list.html', { 'product_list': product_list, 'form': newForm, 'place': place, 'filterForm': filterForm })
注意:要确保你
Product模型里的字段名和代码里的一致,比如地点字段如果是origin_place,那过滤时就要写filter(origin_place=ft_place);价格字段如果是price,排序时就用order_by('price')。
最后修改模板里的表单提交逻辑
把表单改成GET提交,同时添加提交按钮(你原来的模板里没写,用户选了选项没法提交):
{% block content %} <form method="GET"> {{ filterForm }} <button type="submit" class="btn btn-secondary mt-2">过滤</button> </form> <ul class="d-flex flex-row flex-wrap align-content-center justify-content-around align-items-center list-unstyled"> {% for p in product_list %} <li> <div class="card h-100 mt-2 border-dark mb-3" style="max-width: 18rem;"> <img src="{{p.img}}" class="card-img-top" style="height:17.813em;width:auto;" alt="product image"> <div class="card-body"> <h5 class="card-title">{{p.name}}</h5> <p class="card-text">{{p.current_price}}</p> <p class="card-text">Store: {{p.place}}</p> <p class="card-text">Add at {{p.date_add}}</p> <a href="{{p.url}}" target="_blank" class="btn btn-primary">Go to store</a> </div> </div> </li> {% endfor %} </ul> {% endblock %}
这样修改后,用户选择地点和价格选项,点击过滤按钮,页面就会带着过滤参数重新加载,产品列表也会根据选中的条件完成过滤和排序啦!
备注:内容来源于stack exchange,提问作者Dung8466
相关产品推荐
相关产品推荐

