如何在Django ORM中无需循环生成以ref_id为键的字典结构
Django 无循环优化生成指定格式字典
问题背景
我在Django开发中想不使用循环来优化操作,生成特定格式的字典。
模型结构
class Test(BaseClass): id = models.UUIDField(unique=True) ref = models.ForeignKey(Ref) name = models.CharField(max_length=50)
数据表示例数据
+--------------------------------------+--------+----------------+ | id | ref_id | name | +--------------------------------------+--------+----------------+ | 412dacb1-6451-4a1a-b3ac-09a30979b733 | 1 | test | | fa7abc8e-2070-40b6-af84-6a8d78676b89 | 2 | new_rule | | dd70a968-778c-4e45-9044-599effd243a6 | 3 | new_rule_test | +--------------------------------------+--------+----------------+
目标字典格式
需要生成以ref_id为键,值为包含name和id的字典:
{ 1: { "name": "test", "id": UUID("412dacb1-6451-4a1a-b3ac-09a30979b733") }, 2: { "name": "new_rule", "id": UUID("fa7abc8e-2070-40b6-af84-6a8d78676b89") }, 3: { "name": "new_rule_test", "id": UUID("dd70a968-778c-4e45-9044-599effd243a6") } }
现有可行方案(待优化)
尝试过annotate但未成功,目前只有以下代码能用,但数据量庞大时性能不足:
res_dict = Test.objects.filter(publisher_state='Published').values('ref', 'name', 'id') final_dict = {row['ref']: {'name': row['name'], 'id': row['id']} for row in res_dict}
优化方案
1. 使用in_bulk + 字典推导(平衡性能与可读性)
in_bulk可直接返回以指定字段为键的对象字典,避免中间values查询的额外内存开销:
# 按ref_id分组获取符合条件的Test对象 test_objects = Test.objects.filter(publisher_state='Published').in_bulk(field_name='ref') # 转换为目标格式 final_dict = { ref_id: {'name': obj.name, 'id': obj.id} for ref_id, obj in test_objects.items() }
优势:依托Django ORM的优化,减少内存占用,同时保持代码可读性,适合大部分大数据量场景。
2. 原生SQL直接查询(极致性能)
如果数据量极大,可跳过ORM对象实例化,直接操作原始查询结果:
from django.db import connection with connection.cursor() as cursor: cursor.execute(""" SELECT ref_id, name, id FROM yourapp_test WHERE publisher_state = 'Published' """) # 用生成器表达式一次性构建字典,最小化内存占用 final_dict = { row[0]: {'name': row[1], 'id': row[2]} for row in cursor.fetchall() }
优势:完全绕过ORM的对象处理逻辑,性能最优,但牺牲了ORM的兼容性和代码可读性,仅推荐超大数据量场景使用。
注意事项
- 若存在多个Test对象对应同一个ref_id的情况,上述方案会自动保留最后一条查询结果(因字典键唯一),需提前通过
distinct或SQL分组确保每个ref_id仅返回一条数据。 in_bulk要求指定的field_name字段无重复,或你能接受同键覆盖的逻辑。
内容的提问来源于stack exchange,提问作者Shubham Srivastava
相关产品推荐
相关产品推荐

