【速存】深入理解Django ORM:编写高效的数据库查询

简介: 【速存】深入理解Django ORM:编写高效的数据库查询

Django作为一个高级Python Web框架,其自带的对象关系映射(ORM)是其最强大的特性之一。ORM允许开发者以编程语言原生的方式操作数据库,而无需编写原始的SQL查询。本文展示如何在Django项目中利用ORM执行各种数据库查询,并提供详细的代码示例及其解释。

基础查询操作

查询所有对象
from myapp.models import MyModel
# 获取MyModel表中的所有对象
all_entries = MyModel.objects.all()
for entry in all_entries:
    print(entry)
  • from myapp.models import MyModel: 导入应用中定义的模型。
  • MyModel.objects.all(): 获取MyModel表中的所有对象。
  • for entry in all_entries: 遍历查询到的所有对象,并打印。
过滤查询
# 获取所有is_active为True的对象
active_entries = MyModel.objects.filter(is_active=True)
for entry in active_entries:
    print(entry)
  • MyModel.objects.filter(is_active=True): 使用filter方法筛选出字段is_active值为True的对象。
排除查询
# 获取除了is_active为True之外的所有对象
inactive_entries = MyModel.objects.exclude(is_active=True)
for entry in inactive_entries:
    print(entry)
  • MyModel.objects.exclude(is_active=True): 使用exclude方法排除字段is_active值为True的对象。
获取单个对象
# 获取主键为1的单个对象
try:
    entry = MyModel.objects.get(pk=1)
    print(entry)
except MyModel.DoesNotExist:
    print("MyModel with pk=1 does not exist.")
  • MyModel.objects.get(pk=1): 获取主键(Primary Key)为1的对象。
  • try...except: 异常处理,防止查询不到对象时抛出DoesNotExist异常。

复杂查询操作

链式查询
# 获取is_active为True且name以'D'开头的所有对象
filtered_entries = MyModel.objects.filter(is_active=True).filter(name__startswith='D')
for entry in filtered_entries:
    print(entry)
  • filter(is_active=True).filter(name__startswith='D'): 链式调用filter方法来组合筛选条件。
Q对象复杂查询
from django.db.models import Q
# 获取is_active为True或者name以'D'开头的所有对象
complex_entries = MyModel.objects.filter(Q(is_active=True) | Q(name__startswith='D'))
for entry in complex_entries:
    print(entry)
  • from django.db.models import Q: 导入Q对象。
  • Q(is_active=True) | Q(name__startswith='D'): 使用Q对象结合逻辑运算符|(或)构建复杂查询。
跨关联关系查询

假设MyModel有一个外键ForeignKey指向另一个模型RelatedModel

# 获取MyModel的所有对象,其关联的RelatedModel对象的name为'Sample'
related_entries = MyModel.objects.filter(relatedmodel__name='Sample')
for entry in related_entries:
    print(entry)
  • relatedmodel__name='Sample': 使用双下划线__跨关联关系查询RelatedModelname字段。
聚合与分组查询
from django.db.models import Count
# 对MyModel对象按is_active字段进行分组,并计算每组的数量
grouped_entries = MyModel.objects.values('is_active').annotate(count=Count('id'))
for entry in grouped_entries:
    print(f"Active: {entry['is_active']}, Count: {entry['count']}")
  • from django.db.models import Count: 导入Count聚合函数。
  • values('is_active').annotate(count=Count('id')): 使用values方法分组并使用annotate进行聚合,计算每组的数量。

性能优化查询

选择性字段查询
# 仅获取MyModel对象的id和name字段
partial_entries = MyModel.objects.only('id', 'name')
for entry in partial_entries:
    print(entry.id, entry.name)
  • MyModel.objects.only('id', 'name'): 使用only方法来限制查询只返回特定字段。
延迟字段查询
# 在需要时才查询MyModel对象的description字段
deferred_entries = MyModel.objects.defer('description')
for entry in deferred_entries:
    print(entry.description)  # 这里才会实际查询description字段
  • MyModel.objects.defer('description'): 使用defer方法延迟加载指定字段,直到实际访问该字段时才会执行查询。
使用select_related优化关联对象查询

假设MyModel有一个外键ForeignKey指向另一个模型RelatedModel

# 通过select_related获取MyModel和其关联的RelatedModel对象
entries_with_related = MyModel.objects.select_related('relatedmodel')
for entry in entries_with_related:
    print(entry.relatedmodel)
  • MyModel.objects.select_related('relatedmodel'): 使用select_related方法来优化对关联对象的查询,减少数据库的查询次数。
使用prefetch_related优化多对多和反向关联查询

假设MyModelOtherModel有多对多关系。

# 通过prefetch_related获取MyModel及其多对多关联的OtherModel对象
entries_with_others = MyModel.objects.prefetch_related('othermodel_set')
for entry in entries_with_others:
    for other in entry.othermodel_set.all():
        print(other)
  • MyModel.objects.prefetch_related('othermodel_set'): 使用prefetch_related方法来优化多对多和反向关联查询。

赶紧存一下吧!


相关文章
|
3月前
|
人工智能 安全 机器人
无代码革命:10分钟打造企业专属数据库查询AI机器人
随着数字化转型加速,企业对高效智能交互解决方案的需求日益增长。阿里云AppFlow推出的AI助手产品,借助创新网页集成技术,助力企业打造专业数据库查询助手。本文详细介绍通过三步流程将AI助手转化为数据库交互工具的核心优势与操作指南,包括全场景适配、智能渲染引擎及零代码配置等三大技术突破。同时提供Web集成与企业微信集成方案,帮助企业实现便捷部署与安全管理,提升内外部用户体验。
442 12
无代码革命:10分钟打造企业专属数据库查询AI机器人
|
5月前
|
Cloud Native 关系型数据库 分布式数据库
|
5月前
|
并行计算 关系型数据库 MySQL
如何用 esProc 将数据库表转储提速查询
当数据库查询因数据量大或繁忙变慢时,可借助 esProc 将数据导出为文件进行计算,大幅提升性能。以 MySQL 的 3000 万行订单数据为例,两个典型查询分别耗时 17.69s 和 63.22s。使用 esProc 转储为二进制行存文件 (btx) 或列存文件 (ctx),结合游标过滤与并行计算,性能显著提升。例如,ctx 并行计算将原查询时间缩短至 0.566s,TopN 运算提速达 30 倍。esProc 的简洁语法和高效文件格式,特别适合历史数据的复杂分析场景。
|
1月前
|
SQL 存储 数据库
Django模型查询与性能调优:告别N+1问题
本文详解Django数据库查询基础与优化技巧,涵盖QuerySet使用、关联查询(一对多/多对多)、N+1查询问题及解决方案(select_related、prefetch_related)、高级查询方法及项目实战中的数据权限控制实现。
119 0
|
6月前
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
6月前
|
数据库
【YashanDB知识库】数据库用户所拥有的权限查询
【YashanDB知识库】数据库用户所拥有的权限查询
|
6月前
|
存储 运维 监控
百万指标,秒级查询,零宕机——时序数据库 TDengine 在 AIOps 中的硬核实战
本篇文章详细讲述了七云团队在运维平台中如何利用 TDengine 解决海量时序数据存储与查询的实际业务需求。内容涵盖了从数据库选型、方案落地到业务挑战及解决办法的完整过程,特别是分享了升级 TDengine 3.x 时的实战经验,给到有需要的小伙伴参考阅读。
211 1
|
26天前
|
安全 关系型数据库 MySQL
MySQL安全最佳实践:保护你的数据库
本文深入探讨了MySQL数据库的安全防护体系,涵盖认证安全、访问控制、网络安全、数据加密、审计监控、备份恢复、操作系统安全、应急响应等多个方面。通过具体配置示例,为企业提供了一套全面的安全实践方案,帮助强化数据库安全,防止数据泄露和未授权访问,保障企业数据资产安全。
|
11天前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
47 3