首页 后端开发 Python教程 需要修复的常见 Django ORM 错误

需要修复的常见 Django ORM 错误

Jan 04, 2025 am 12:49 AM

Common Django ORM Mistakes to fix

Django ORM 是 django 最强大的功能之一。它抽象化了与数据库交互的大部分复杂性,让开发人员可以使用 Pythonic 语法而不是原始 SQL 来操作数据。所有这些 ORM 函数都会生成 SQL 查询,如果处理不当,这些查询可能会成为瓶颈。
本博客重点介绍了使用 Django ORM 时的常见错误,并提供了保持查询高效、可维护和高性能的技巧。

1. N 1 查询问题

当您的代码触发一个查询来获取一组记录,然后再次运行 N 个附加查询来获取相关数据时,就会出现 N 1 查询问题。

blogs = Blog.objects.all()    # 1 Query
for blog in blogs:
    print(blog.author.name)   # N additional queries
登录后复制
登录后复制

在上面的示例中,在循环内访问 blog.author.name 会导致 Django 单独获取每个博客的作者记录,从而导致 N 个额外的查询。

如何解决
对单个相关对象(例如,ForeignKey 或 OneToOneField)使用 select_lated,因为它执行 SQL JOIN 以在一个查询中检索主对象及其相关对象。对于多对多、多对一或反向关系,请使用 prefetch_lated,它在单独的查询中获取相关数据,但在 Python 中有效地将它们组合起来,避免 N 1 问题。

# With select_related
blogs = Blog.objects.select_related('author').all()

# With prefetch_related
authors = Author.objects.prefetch_related('blogs').all()
登录后复制
登录后复制

2. 过度使用.all()和.filter()

开发人员经常链接多个过滤器或使用 .all() ,然后对同一查询集重复查询:

blogs = Blog.objects.all()
active_blogs = blogs.filter(is_archived=False)
popular_blogs = blogs.filter(views__gte=1000)
登录后复制
登录后复制

尽管 Django 尝试通过仅在需要时延迟评估查询集来优化查询集,但对同一查询集数据重复调用过滤器仍然会导致对数据库不必要的命中。

如何解决
在一条语句中组合过滤器允许 django 生成单个 SQL 查询。

popular_active_blogs = Blog.objects.filter(is_archived=False, views__gte=1000)
登录后复制

3. 不利用values()或values_list()

有时我们只需要特定字段而不是模型的所有字段数据。在此期间使用 .values().values_list() 可以更高效。

titles = Blog.objects.values('title')
or
titles = Blog.objects.values_list('title', flat=True)
# values() returns a list of dictionaries.
# values_list() can return tuples or flat values if flat=True is provided.
登录后复制

通过仅获取所需的列,可以减少从数据库传输的数据量,从而提高性能。

4. 低效的聚合和注释

重复调用 .aggregate().annotate() 可能会导致多次查询。具有多个注释的复杂查询可能会导致 SQL 查询效率低下,从而可能导致繁重的数据库操作。

# Example of multiple aggregate
total_count = Blog.objects.aggregate(Count('id'))
author_count = Blog.objects.aggregate(Count('author'))
average_views = Blog.objects.aggregate(Avg('views'))
登录后复制

推荐

blogs = Blog.objects.all()    # 1 Query
for blog in blogs:
    print(blog.author.name)   # N additional queries
登录后复制
登录后复制

5. 不使用数据库索引

索引使数据库能够快速定位和检索数据,避免缓慢的全表扫描,从而提高查询性能。索引优化了过滤、排序和连接等操作,使得对频繁访问的字段的查询速度更快。频繁查询字段上缺少数据库索引会大大降低性能。
如何在 Django 中添加索引

# With select_related
blogs = Blog.objects.select_related('author').all()

# With prefetch_related
authors = Author.objects.prefetch_related('blogs').all()
登录后复制
登录后复制

索引可以加快读取速度,但会减慢写入速度。因此,只对那些经常需要查询的字段建立索引。

6. 不使用缓存

当我们必须查询计算成本昂贵或很少更改的数据时,请使用缓存。即使缓存 5 分钟,也可以节省重复查询、复杂计算和不经常更改的查询。

blogs = Blog.objects.all()
active_blogs = blogs.filter(is_archived=False)
popular_blogs = blogs.filter(views__gte=1000)
登录后复制
登录后复制

7. 原始 SQL

有时,Django ORM 无法有效地表达复杂的查询或批量操作。虽然 Django 提供 .extra() 或 .raw(),但原始 SQL 使用应该是最后的手段,因为它:

  • 失去了 ORM 的许多好处
  • 可能导致不可读或容易出错的代码

确保输入得到正确清理并保持原始 SQL 查询可维护。

应用这些技巧,您将提高 Django 应用程序的性能,同时保持代码整洁和可维护。并建议在开发环境中使用 Django 调试工具栏 来监控和分析执行的查询数量、执行时间和 SQL 语句。

以上是需要修复的常见 Django ORM 错误的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1667
14
CakePHP 教程
1426
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1255
24
Python:游戏,Guis等 Python:游戏,Guis等 Apr 13, 2025 am 12:14 AM

Python在游戏和GUI开发中表现出色。1)游戏开发使用Pygame,提供绘图、音频等功能,适合创建2D游戏。2)GUI开发可选择Tkinter或PyQt,Tkinter简单易用,PyQt功能丰富,适合专业开发。

Python与C:学习曲线和易用性 Python与C:学习曲线和易用性 Apr 19, 2025 am 12:20 AM

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

Python和时间:充分利用您的学习时间 Python和时间:充分利用您的学习时间 Apr 14, 2025 am 12:02 AM

要在有限的时间内最大化学习Python的效率,可以使用Python的datetime、time和schedule模块。1.datetime模块用于记录和规划学习时间。2.time模块帮助设置学习和休息时间。3.schedule模块自动化安排每周学习任务。

Python vs.C:探索性能和效率 Python vs.C:探索性能和效率 Apr 18, 2025 am 12:20 AM

Python在开发效率上优于C ,但C 在执行性能上更高。1.Python的简洁语法和丰富库提高开发效率。2.C 的编译型特性和硬件控制提升执行性能。选择时需根据项目需求权衡开发速度与执行效率。

Python标准库的哪一部分是:列表或数组? Python标准库的哪一部分是:列表或数组? Apr 27, 2025 am 12:03 AM

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

Python:自动化,脚本和任务管理 Python:自动化,脚本和任务管理 Apr 16, 2025 am 12:14 AM

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。

学习Python:2小时的每日学习是否足够? 学习Python:2小时的每日学习是否足够? Apr 18, 2025 am 12:22 AM

每天学习Python两个小时是否足够?这取决于你的目标和学习方法。1)制定清晰的学习计划,2)选择合适的学习资源和方法,3)动手实践和复习巩固,可以在这段时间内逐步掌握Python的基本知识和高级功能。

Python vs. C:了解关键差异 Python vs. C:了解关键差异 Apr 21, 2025 am 12:18 AM

Python和C 各有优势,选择应基于项目需求。1)Python适合快速开发和数据处理,因其简洁语法和动态类型。2)C 适用于高性能和系统编程,因其静态类型和手动内存管理。

See all articles