如何在Django-admin(或Jet)中实现商品价格范围过滤?
在Django Admin(含Jet)中实现商品价格范围过滤
当然可以实现!不管是原生Django Admin还是Django Jet,都能轻松满足你输入价格区间筛选商品的需求,下面给你两种场景下的具体实现方案:
一、原生Django Admin实现方案
方案1:预定义价格区间过滤(快速简单)
如果你的价格区间是固定的几个常用范围,可以用Django自带的SimpleListFilter快速实现:
- 在你的
admin.py文件中,定义一个自定义过滤器类:
from django.contrib import admin from .models import Product class PriceRangeFilter(admin.SimpleListFilter): title = '价格范围' # 过滤器在Admin侧边栏显示的名称 parameter_name = 'price_range' # URL中用来传递过滤参数的标识 def lookups(self, request, model_admin): # 定义可选的价格区间选项,可根据业务需求调整 return ( ('0-50', '0-50元'), ('50-100', '50-100元'), ('100-200', '100-200元'), ('200+', '200元以上'), ) def queryset(self, request, queryset): # 根据用户选中的区间过滤商品 if self.value() == '0-50': return queryset.filter(price__gte=0, price__lte=50) elif self.value() == '50-100': return queryset.filter(price__gte=50, price__lte=100) elif self.value() == '100-200': return queryset.filter(price__gte=100, price__lte=200) elif self.value() == '200+': return queryset.filter(price__gte=200) # 未选中任何区间时返回全部商品 return queryset
- 将这个过滤器添加到
ProductAdmin的list_filter配置中:
@admin.register(Product) class ProductAdmin(admin.ModelAdmin): list_display = ('title', 'amount', 'price') # 列表页显示的字段 list_filter = (PriceRangeFilter,) # 加入自定义价格过滤器
配置完成后,在Admin的侧边栏就会出现价格范围的下拉选项,选择后就能自动筛选对应区间的商品。
方案2:手动输入价格区间(灵活自定义)
如果需要让用户自由输入任意的min_price和max_price,我们可以通过自定义过滤器模板来实现:
- 先创建一个自定义过滤器类,指定模板路径:
class CustomPriceRangeFilter(admin.SimpleListFilter): title = '自定义价格范围' parameter_name = 'custom_price' def lookups(self, request, model_admin): # 返回空元组,因为我们不需要预定义选项,仅用于触发模板渲染 return () def queryset(self, request, queryset): # 获取用户输入的最低/最高价格并过滤 min_price = request.GET.get('min_price') max_price = request.GET.get('max_price') if min_price: queryset = queryset.filter(price__gte=float(min_price)) if max_price: queryset = queryset.filter(price__lte=float(max_price)) return queryset def template(self): # 指定自定义模板的路径,需提前创建该文件 return 'admin/filters/custom_price_range.html'
- 在项目的
templates/admin/filters/目录下创建custom_price_range.html模板文件,内容如下:
{% load i18n %} <h3>{{ title }}</h3> <div class="form-row"> <label for="min_price">{% trans '最低价格:' %}</label> <input type="number" step="0.01" name="min_price" id="min_price" value="{{ request.GET.min_price }}"> </div> <div class="form-row"> <label for="max_price">{% trans '最高价格:' %}</label> <input type="number" step="0.01" name="max_price" id="max_price" value="{{ request.GET.max_price }}"> </div> <div class="form-row"> <button type="submit" class="button">{% trans '筛选' %}</button> {% if request.GET.min_price or request.GET.max_price %} <a href="{{ request.path }}" class="button">{% trans '重置' %}</a> {% endif %} </div>
- 将自定义过滤器添加到
ProductAdmin中:
@admin.register(Product) class ProductAdmin(admin.ModelAdmin): list_display = ('title', 'amount', 'price') list_filter = (CustomPriceRangeFilter,)
这样在Admin侧边栏就会出现两个输入框,用户可以输入任意价格范围,点击筛选按钮就能得到符合条件的商品列表。
二、Django Jet实现方案
Django Jet作为Django Admin的增强扩展,完全兼容原生的过滤器实现,所以上面两种原生方案都可以直接在Jet中使用。Jet会自动将原生过滤器适配成自己的UI风格,体验更美观。
如果你想进一步贴合Jet的设计,只需要把自定义模板的样式调整成Jet的风格即可(参考Jet自带过滤器的模板写法),核心的过滤逻辑无需改动。
内容的提问来源于stack exchange,提问作者Kamil Saitov




