要有效的使用ORM,意味着需要多少要明白它是如何查询数据库的。本文我将重点介绍如何有效使用 Django ORM系统访问中到大型的数据集。...Django的queryset是惰性的 Django的queryset对应于数据库的若干记录(row),通过可选的查询来过滤。...的 当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。...print(star.name) 当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。...所以使用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询。
此时并未执行数据库查询 print news_list # 用时方执行查询操作 何时它们被执行. # 用时方执行查询操作 print news_list 数据如何被缓存 # 这样的QuerySet...使用with模板标签 在模板中使用QuerySet缓存,需要使用with标签 使用iterator() 获取大量数据时 news_list = News.objects.filter(title__contains...=u'违法') for news in news_list.iterator(): print news 让数据库做它自己的工作 基本概念 使用 filter and exclude 在数据库层面执行过滤操作...with的使用是关键 每次的QuerySet.count()调用都会产生查询 使用 QuerySet.update() 和 delete() 批量更新使用 QuerySet.update() 批量删除使用...批量插入 用 django.db.models.query.QuerySet.bulk_create() 批量创建对象,减少SQL查询的 数量。
你可以将过滤器保持一整天,直到查询集 需要求值时,Django 才会真正运行这个查询。...iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。...所以使 #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询。...总结: queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。 使用exists()和iterator()方法可以优化程序对内存的使用。...select_related 返回一个QuerySet,当执行它的查询时它沿着外键关系查询关联的对象的数据。它会生成一个复杂的查询并引起性能的损耗,但是在以后使用外键关系时将不需要数据库查询。
使用iterator() 当你有很多对象时,QuerySet的缓存行为会占用大量的内存。这种情况下,采用iterator()解决。...不要获取你不需要的东西 使用QuerySet.values()和values_list() 当你仅仅想要一个带有值的字典或者列表,并不需要使用ORM模型对象时,可以适当使用values()。...另外,当建立起一个带有延迟字段的模型时,要意识到一些(小的、额外的)消耗会在Django内部产生。...{{ emails|length }}调用了QuerySet.len()方法,填充了缓存的剩余部分,而且并没有执行另一次查询。 for循环的迭代器访问了已经缓存的数据。...整体插入 创建对象时,尽可能使用bulk_create()来减少SQL查询的数量。
你可以将过滤器保持一整天,直到查询集 需要求值时,Django 才会真正运行这个查询。 ?...()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。...所以使 #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询。...总结: queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。 使用exists()和iterator()方法可以优化程序对内存的使用。...select_related 返回一个QuerySet,当执行它的查询时它沿着外键关系查询关联的对象的数据。它会生成一个复杂的查询并引起性能的损耗,但是在以后使用外键关系时将不需要数据库查询。
要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql....是具有cache的 当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。...iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。...所以使 #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询 总结: queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库...使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能 会造成额外的数据库查询。
可以使用下列方法对QuerySet提交查询操作: 迭代:QuerySet是可迭代的,在首次迭代查询集时执行实际的数据库查询。...step“参数,Django 将执行数据库查询并返回一个列表。...使用这种方法作为最后的手段,这是一个旧的API,在将来的某个时候可能被弃用。仅当无法使用其他查询方法表达查询时才使用它。 例如: >>> qs.extra( ......而iterator()将直接读取结果,不在QuerySet级别执行任何缓存。对于返回大量只需要访问一次的对象的QuerySet,这可以带来更好的性能,显著减少内存使用。...请注意,在已经提交了的iterator()上使用QuerySet会强制它再次提交数据库操作,进行重复查询。
当第一次迭代它时,它将执行其数据库查询。例如,这将打印数据库中所有条目的标题。...切片未执行的QuerySet通常会返回另一个未执行的Query Set。但是,如果使用切片语法的step参数,Django将执行数据库查询并返回一个列表。...还要注意,即使对未执行的QuerySet进行切片并返回另一个未执行的Query Set,也不允许对其进行进一步修改(例如,添加更多筛选器或修改排序),因为它无法很好地转换为SQL,也没有明确的含义。...这是为了方便Python交互式解释器,因此当以交互方式使用API时,可以立即看到结果。 len()调用len()时,将执行QuerySet。正如所期望的,这将返回结果列表的长度。...[{'id': 1, 'name': 'Beatles Blog'}]> 类QuerySet(模型=无,查询=无,使用=无,提示=无) 通常,当与QuerySet交互时,将通过链过滤器使用它。
`id` = 1 迭代:在首次迭代查询集时会执行数据库查询 切片(限制查询集):对查询集执行切片操作时,指定 step 参数 序列化/缓存 repr:对查询集调用 repr 函数 len:对查询集调用...当首次对 QuerySet 的所有实例进行求值时,会将查询结果保存到 QuerySet 的缓冲中。当再访问该 QuerySet 时,会直接从缓冲中取数据。...如果 QuerySet 数量很大不希望被缓存,遍历时使用 iterator 方法: blogs = Blog.objects.all() for blog in blogs.iterator():...`author_id` IN (1) 如果查询出关联对象的 QuerySet 之后,再对该 QuerySet 执行查询条件,会使该 QuerySet 失效(也就是需要再次访问数据库)。...如果在查询关联对象时需要使用查询条件,可以使用 Prefetch 对象,下面是一个示例: from django.db.models import Prefetch authors = Author.objects.prefetch_related
django应用的每个模型至少拥有一个 管理器。 管理器类的工作方式在 执行查询文档中阐述,而这篇文档涉及了自定义管理器行为的模型选项。...因此,要决定默认的管理器时,要小心谨慎,仔细考量,这样才能避免重写 get_queryset() 导致无法正确地获得数据。...使用管理器访问关联对象 默认情况下,在访问相关对象时(例如choice.poll),Django 并不使用相关对象的默认管理器,而是使用一个”朴素”管理器类的实例来访问。...解决办法就是在另一个基类中添加新的管理器,然后继承时将其放在默认管理器所在的基类 之后。...在整个这一节中,我们将那种由 Django 为你创建的管理器称之为 “自动管理器”,既有因为没有管理器而被 Django 自动添加的默认管理器, 也包括在访问关联模型时使用的临时管理器。
QuerySet缓存 Django的QuerySet具有缓存机制,这意味着在首次执行QuerySet时,Django会将结果缓存起来,以便在后续的相同查询中直接使用缓存结果,而不是再次执行数据库查询。...缓存机制:当QuerySet被首次执行时,Django会将结果缓存起来。...避免缓存失效:在某些情况下,QuerySet缓存可能会失效。例如,当对QuerySet进行切片操作时,缓存可能会失效。为了避免这种情况,可以使用iterator()方法来禁用缓存。...例如: queryset = MyModel.objects.filter(name='example').iterator() # 禁用缓存,每次查询都会重新执行数据库查询 first_result...以下是一些常见的性能瓶颈及其识别方法: 数据库查询:使用django-debug-toolbar等工具查看执行的SQL查询,识别慢查询或不必要的查询。
一、orm使用方式: orm操作可以使用类实例化,obj.save的方式,也可以使用create()的形式 二、QuerySet数据类型 QuerySet与惰性机制 所谓惰性机制:Publisher.objects.all...()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行。...QuerySet特点: 可迭代的 可切片 惰性计算和缓存机制 def queryset(request): #切片 应用分页 books=models.Book.objects.all...SQL操作 # query_set缓存机制1次数据库查询结果query_set都会对应一块缓存,再次使用该query_set时,不会发生新的SQL操作; books=models.Book.objects.all...; models.Publish.objects.all().iterator() return HttpResponse('OK') 为上一章内容再增添一个知识点 ① 字段参数 AutoField
() 来更高效的获取数据条数 用 list() 把 QuerySet 强制转换成 list 时 强转成 bool 类型或者 作为 if 条件 时 如果 QuerySet 的查询结果至少有一个(数据对象...新创建的 QuerySet 的缓存(cache)是空的,QuerySet 第一次取值执行(evaluatad)的时候进行数据库查询操作,Django 会将查询结果保存到 QuerySet 的 cache...比如,每次获取一个明确的索引值都会执行一次数据库操作 # 下面的操作执行了两次数据库查询 queryset = Entry.objects.all() print(queryset[5]) # 查询数据库...,里面包含的对象都是满足你给出的查询参数(条件)的,多个查询(关键字)参数以逗号间隔,对应到 SQL 语句中是 AND 连接,如果你想执行更多复杂的操作(比如 OR 或)可以使用 Q 对象 Q对象 的使用...过滤字段 .none() 创建空的 QuerySet 调用 .none() 方法会创建一个空的 QuerySet ,里面不包含任何数据对象,并且在取值时也不会执行任何数据库操作(是 EmptyQuerySet
执行一下两行命令来创建数据库的表。 ? 运行成功的结果如下: ? 在数据库也会发现我们刚才新建的表 ? 5 插入与查询数据 Author 和 Book 表已经新建成功了。你可能有这样的疑惑。...只需要执行上步的两行命令即可 ? Django 会对 models.py 进行检测,自动发现需要更改的,应用到数据库中去。 1)创建对象 打开 python 终端,利用命令行来创建一个对象。 ?...2)查询数据 同样在 python 终端下,执行下面的命令。 ? 3)使用 QuerySet API 查询数据 从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet。...4)使用 QuerySet 创建数据 我们之前创建对象都是通过命令行。但是在生产环境中,显然不能这么操作。那么我们要如何在 py 文件中创建对象呢?...6)使用 QuerySet 删除数据 删除的用法跟创建用法是大同小异,在获取结果后面添加 delete() 方法即可。 ? Django 学习之旅不知不觉到了终点了。终点又是另一个新的起点。
,只有当用到这个QuerySet时,才会查询数据库求值。...另外,查询到的QuerySet又是缓存的,当再次使用同一个QuerySet时,并不会再查询数据库,而是直接从缓存获取(不过,有一些特殊情况)。...我们修改一下代码,如下,遍历一开始也是先执行查询得到a,但当执行print (e.blog.name)时,还需要再次查询数据库获取blog实体。...,但不建议这样做,因为混和查询时Q对象要放前面,这样就有难免忘记顺序而出错,所以如果使用Q对象,那就全部用Q对象。...,关联表的字段也不会返回,只有当我们通过Author instance用关联表时,Django才会再次查询数据库获取值。
执行查询 一旦你建立好数据模型之后,django会自动生成一套数据库抽象的API,可以让你执行增删改查的操作。这篇文档阐述了如何使用这些API。关于所有模型检索选项的详细内容,请见数据模型参考。...你可以一直添加过滤器,在这个过程中,Django 不会执行任何数据库查询,除非 QuerySet 被执行....QuerySet 第一次运行时,会执行数据库查询,接下来 Django 就在 QuerySet 的缓存中保存查询的结果,并根据请求返回这些结果(比如,后面再次调用这个 QuerySet 的时候)。...如果你要执行更复杂的查询(比如,实现筛选条件的 OR 关系),可以使用 Q 对象。 Q 对象(django.db.models.Q)是用来封装一组查询关键字的对象。...在调用 update 时可以使用 F() 对象 来把某个字段的值更新为另一个字段的值。
distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。...如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。...同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。 示例:查询作者名字是小仙女并且不是2018年出版的书的书名。...[('番茄物语',)]> 查询函数可以混合使用Q 对象和关键字参数。...ORM执行原生的SQL # extra # 在QuerySet的基础上继续执行子语句 # extra(self, select=None, where=None, params=None, tables
exclude() 聚合可以和filter和exclude一起使用: >>> from django.db.models import Count, Avg >>> Book.objects.filter...)).filter(num_authors__gt=1) 编写一个包含annotate()和filter()从句的复杂查询时,要特别注意作用于QuerySet的从句的顺序顺序的不同,产生的意义也不同:...在第二个查询中,过滤器在注解之前,所以,在计算注解值时,过滤器就限制了参与运算的对象的范围 order_by() 可以根据聚合值进行排序 >>> Book.objects.annotate(num_authors...=Count('authors')).order_by('num_authors') values() 通常,注解annotate是添加到每一个对象上的,一个执行了注解操作的查询集 QuerySet 所返回的结果中...默认排序下使用聚合: from django.db import models class Item(models.Model): name = models.CharField(max_length
查询集,也称查询结果集、QuerySet,表示从数据库中获取的对象集合。 当调用如下过滤器方法时,Django会返回查询集(而不是简单的列表): all():返回所有数据。...2 两大特性 1)惰性执行 创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用 例如,当执行如下语句时,并未进行数据库查询,只是创建了一个查询集books...使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。...情况一:如下是两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,增加了数据库的负载。...对查询集进行切片后返回一个新的查询集,不会立即执行查询。
2017年12月2日,Django官方发布了2.0版本,成为多年来的第一次大版本提升,那么2.0对广大Django使用者有哪些变化和需要注意的地方呢?...django.conf.urls.include()方法现在可以从django.urls导入,也就是你可以使用from django.urls import include, path, re_path...squashmigrations --squashed-name选项; Models模型 新增StrIndex数据库函数; 对于Oracle数据库,AutoField和BigAutoField现在会生成identity列; QuerySet.iterator...; QuerySet.values_list()新增named参数,用于获取命名的元组结果; 新的FilteredRelation类允许为查询集增加一个ON从句; Pagination分页 增加Paginator.get_page...QuerySet.reverse()和last()不能用于切片后的查询集 对切片后的查询集使用反转和获取最近对象的操作将弹出异常,如下所示: >>> Model.objects.all()[:2].reverse