如何在Django中实现商品按价格升降序等规则排序并渲染
Django商品列表多规则排序功能实现方案
1. 类视图排序逻辑实现
核心是在类视图的get_queryset方法中读取请求参数的排序规则,同时加白名单校验避免SQL注入风险,示例代码如下:
from django.views.generic import ListView from .models import Item class ProductListView(ListView): model = Item template_name = "your_template.html" context_object_name = "item_list" # 排序规则白名单,仅允许指定字段排序 ALLOWED_SORT_FIELDS = { "price_asc": "price", "price_desc": "-price", "sales_desc": "-sales_volume", "created_desc": "-create_time" } def get_queryset(self): queryset = super().get_queryset() # 如需先按子分类筛选,在此处添加对应逻辑 subcategory_id = self.request.GET.get("subcategory_id") if subcategory_id: queryset = queryset.filter(subcategory_id=subcategory_id) # 处理排序逻辑 sort_key = self.request.GET.get("sort", "price_asc") # 默认按价格升序 if sort_key in self.ALLOWED_SORT_FIELDS: queryset = queryset.order_by(self.ALLOWED_SORT_FIELDS[sort_key]) return queryset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 把当前排序规则传到模板,方便做选中高亮 context["current_sort"] = self.request.GET.get("sort", "price_asc") # 把当前其他筛选参数传到模板,避免排序时丢失筛选条件 context["subcategory_id"] = self.request.GET.get("subcategory_id", "") return context
2. 前端模板排序链接配置
要保留当前页面的其他筛选参数(比如子分类ID、搜索关键词),仅替换排序参数,示例代码如下:
<div class="sort-options"> <a href="?sort=price_asc&subcategory_id={{ subcategory_id }}" class="{% if current_sort == 'price_asc' %}active{% endif %}"> 价格从低到高 </a> <a href="?sort=price_desc&subcategory_id={{ subcategory_id }}" class="{% if current_sort == 'price_desc' %}active{% endif %}"> 价格从高到低 </a> <a href="?sort=sales_desc&subcategory_id={{ subcategory_id }}" class="{% if current_sort == 'sales_desc' %}active{% endif %}"> 销量从高到低 </a> <a href="?sort=created_desc&subcategory_id={{ subcategory_id }}" class="{% if current_sort == 'created_desc' %}active{% endif %}"> 最新发布 </a> </div> <!-- 渲染商品列表 --> <div class="item-list"> {% for item in item_list %} <div class="item-card"> <h3>{{ item.name }}</h3> <p>价格:¥{{ item.price }}</p> <!-- 其他商品信息 --> </div> {% endfor %} </div>
3. 常见问题排查
- 确认
Item模型的price字段是数值类型(IntegerField、DecimalField),不要用CharField存储价格 - 点击排序链接后检查浏览器地址栏是否带了正确的
sort参数,确认参数值在白名单范围内 - 如果有分页需求,分页组件的链接也要带上
sort和其他筛选参数,避免翻页时排序失效
内容的提问来源于stack exchange,提问作者Shreyash mishra
相关产品推荐
相关产品推荐

