Django如何通过不同属性的slug动态过滤ETF模型 避免重复编写过滤方法
Django多维度筛选冗余查询优化方案
核心思路:通过动态构造Django ORM查询参数+合法维度白名单的方式,完全消除重复的查询方法,新增筛选维度仅需修改一行配置。
最简实现(无特殊自定义逻辑场景)
适合所有筛选维度的查询逻辑完全一致(都是关联表slug匹配、按aum倒序)的场景,直接删掉整个Categories_selector类即可,修改views.py如下:
from django.http import Http404 from .models import ETF # 定义允许筛选的维度白名单,新增维度仅需在这里加对应模型字段名即可 ALLOWED_FILTER_CATEGORIES = {'theme', 'sector', 'region', 'industry'} def get_etf_list(request, categories_slug, category_slug): # 校验筛选维度合法性,防止非法字段查询触发报错或安全问题 if categories_slug not in ALLOWED_FILTER_CATEGORIES: raise Http404("筛选维度不存在") # 动态构造查询参数 filter_kwargs = { f"{categories_slug}__slug": category_slug } filtered_results = ETF.objects.filter(**filter_kwargs).order_by('-aum') return render(request, "etf/list_etf.html", { "ETFs": filtered_results })
该方案优势:
- 完全消除冗余代码,原有
Categories_selector类可直接删除 - 新增筛选维度仅需在
ALLOWED_FILTER_CATEGORIES集合中添加对应模型字段名,无需新增任何查询方法 - 自带参数校验,避免非法请求引发问题
进阶实现(有自定义逻辑场景)
如果不同筛选维度需要不同的排序规则、额外过滤条件,可以用字典配置替代单独方法,灵活性更高,示例如下:
from django.http import Http404 from .models import ETF # 每个维度可独立自定义查询规则,新增维度仅需加对应配置项 CATEGORY_CONFIG = { "theme": { "filter_field": "theme__slug", "order_by": "-aum" }, "sector": { "filter_field": "sector__slug", "order_by": "-aum" }, "region": { "filter_field": "region__slug", "order_by": "full_name" # 比如区域维度按基金名称正序排序 }, } def get_etf_list(request, categories_slug, category_slug): if categories_slug not in CATEGORY_CONFIG: raise Http404("筛选维度不存在") config = CATEGORY_CONFIG[categories_slug] filtered_results = ETF.objects.filter(**{ config["filter_field"]: category_slug }).order_by(config["order_by"]) return render(request, "etf/list_etf.html", { "ETFs": filtered_results })
注意:请确保ETF模型中已经定义了白名单/配置中对应的关联字段,你提供的示例代码中ETF模型暂时缺少
theme的ManyToManyField定义,需要补全后theme维度才能正常使用。
以上两种方案都无需修改原有urls.py逻辑,兼容现有路由规则。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

