如何在Django站点中通过URL传参实现ListView下的商品排序功能
Django ListView 通过URL参数实现商品排序方案
视图代码修改
在原有ProductList类中新增排序规则白名单映射,在get_queryset中读取URL的s查询参数,匹配合法规则后执行排序:
class ProductList(ListView): template_name = 'products/store.html' paginate_by = 8 # 排序规则映射:key为URL传入的参数值,value为Django ORM对应的排序字段 SORT_RULES = { 'price-asc': 'price', 'price-desc': '-price', 'sales-desc': '-sales', 'newest': '-create_time', # 可根据业务需求自行扩展其他排序规则 } def get_queryset(self): queryset = Product.objects.get_active_products() sort_param = self.request.GET.get('s') # 仅当参数命中合法规则时才执行排序,避免非法参数报错 if sort_param in self.SORT_RULES: queryset = queryset.order_by(self.SORT_RULES[sort_param]) return queryset
前端下拉菜单写法
下拉菜单的a标签直接携带s参数即可,同时可保留当前分页参数,避免排序后自动回到第一页:
<div class="sort-dropdown"> <a href="?s=price-asc{% if request.GET.page %}&page={{ request.GET.page }}{% endif %}">价格升序</a> <a href="?s=price-desc{% if request.GET.page %}&page={{ request.GET.page }}{% endif %}">价格降序</a> <a href="?s=sales-desc{% if request.GET.page %}&page={{ request.GET.page }}{% endif %}">销量优先</a> <a href="?s=newest{% if request.GET.page %}&page={{ request.GET.page }}{% endif %}">最新上架</a> </div>
注意事项
- 排序规则白名单是必须项,禁止直接将用户传入的参数传入
order_by方法,避免SQL注入和非法字段查询报错 - 如果页面存在其他筛选条件(比如分类、价格区间、搜索关键词),可在拼接URL时保留对应参数,避免排序后原有筛选条件丢失
内容的提问来源于stack exchange,提问作者Mohammadali Kashani
相关产品推荐
相关产品推荐

