You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Django Model的Filter查询方法及按所有列动态分组?

Django ProductionPlan模型的两个需求实现方案

一、按所有可用字段动态分组(regroup)

实现思路

动态分组的核心是先筛选出模型可用于分组的字段,再根据传入的分组参数,在后端查询或前端渲染阶段完成分组逻辑:

  1. 筛选可分组字段:排除自动生成的关联后缀字段(如bills_of_material_id)、非业务需求的字段类型(如DurationField),保留用户定义的核心字段。
  2. 后端分组查询:接收前端传入的分组字段,验证合法性后用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:45:50