如何获取Django Model的Filter查询方法及按所有列动态分组?
Django ProductionPlan模型的两个需求实现方案
一、按所有可用字段动态分组(regroup)
实现思路
动态分组的核心是先筛选出模型可用于分组的字段,再根据传入的分组参数,在后端查询或前端渲染阶段完成分组逻辑:
- 筛选可分组字段:排除自动生成的关联后缀字段(如
bills_of_material_id)、非业务需求的字段类型(如DurationField),保留用户定义的核心字段。 - 后端分组查询:接收前端传入的分组字段,验证合法性后用
values+annotate实现分组聚合;或在模板中用regroup标签渲染分组结果。
代码示例
1. 获取可分组字段列表
from django.db.models import DurationField, ForeignKey def get_groupable_fields(model): exclude_field_types = (DurationField,) groupable_fields = [] for field in model._meta.get_fields(): # 跳过非实体字段、自动生成的关联ID字段 if not field.concrete or field.name.endswith('_id'): continue # 跳过指定类型的字段(可根据业务调整) if isinstance(field, exclude_field_types): continue groupable_fields.append(field.name) return groupable_fields # 调用示例:获取ProductionPlan的可分组字段 valid_group_fields = get_groupable_fields(ProductionPlan)
2. 后端动态分组查询
def dynamic_group_query(group_field): valid_fields = get_groupable_fields(ProductionPlan) if group_field not in valid_fields: raise ValueError("不支持该分组字段") # 以统计每组数据数量为例,可根据需求调整聚合逻辑 grouped_result = ProductionPlan.objects.values(group_field)\ .annotate(total=models.Count('id'))\ .order_by(group_field) return grouped_result
3. 模板中动态渲染分组
将查询集和分组字段传入模板后,用regroup标签实现前端分组:
{% regroup plan_list by request.GET.group_field as grouped_plans %} {% for group in grouped_plans %} <h3>分组:{{ group.grouper }}</h3> <ul> {% for plan in group.list %} <li>{{ plan.id }} - {{ plan.status }}</li> {% endfor %} </ul> {% endfor %}
二、实现get_methods_for_filter函数获取所有支持的Filter查询方法
实现思路
Django每个字段都内置了get_lookups()方法,可获取该字段支持的所有查询规则(lookup)。遍历模型所有字段,拼接成字段名__查询规则的格式,汇总去重后返回即可。
代码实现
def get_methods_for_filter(model): filter_methods = set() for field in model._meta.get_fields(): if not field.concrete: continue # 获取当前字段支持的所有查询方法 lookups = field.get_lookups().keys() for lookup in lookups: filter_methods.add(f"{field.name}__{lookup}") # 外键字段额外添加关联模型主键的查询规则 if isinstance(field, ForeignKey): related_pk = field.remote_field.model._meta.pk.name filter_methods.add(f"{field.name}__{related_pk}") # 排序后返回列表,便于使用 return sorted(filter_methods) # 调用示例:获取ProductionPlan支持的所有Filter方法 all_filter_methods = get_methods_for_filter(ProductionPlan)
说明
- 函数会自动适配不同字段类型的查询规则:
- 字符字段(如
status)生成status__icontains、status__startswith等 - 日期字段(如
start_date)生成start_date__gte、start_date__contains等 - 数字字段(如
quantity)生成quantity__lte、quantity__exact等 - 外键字段(如
bills_of_material)生成bills_of_material__id、关联模型其他字段的查询规则
- 字符字段(如
- 用
set去重,避免重复规则,最终返回排序后的列表。
内容的提问来源于stack exchange,提问作者Abdullah Sokrab
相关产品推荐
相关产品推荐

