{"title":"执行查询","version":"6.1","locale":"zh-hans","docname":"topics/db/queries","url":"/zh-hans/6.1/topics/db/queries/","canonical":"https://djangodocs.dev/zh-hans/6.1/topics/db/queries/","summary":"一旦创建数据模型后，Django 自动给予你一套数据库抽象 API，允许你创建，检索，更新和删除对象。本页介绍如何使用这些 API。","html":"<h1>执行查询<a class=\"heading-anchor\" href=\"#making-queries\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>一旦创建 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/models/\"><span class=\"doc\">数据模型</span></a> 后，Django 自动给予你一套数据库抽象 API，允许你创建，检索，更新和删除对象。本页介绍如何使用这些 API。参考 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/\"><span class=\"doc\">数据模型参考</span></a> 获取所有查询选项的完整细节。</p>\n<p>在本指南中（以及在参考资料中），我们将提及以下模型，它们构成了一个博客应用程序：</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span> <span class=\"nn\">datetime</span> <span class=\"kn\">import</span> date\n\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Blog</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    tagline <span class=\"o\">=</span> models<span class=\"o\">.</span>TextField<span class=\"p\">()</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>name\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Author</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    email <span class=\"o\">=</span> models<span class=\"o\">.</span>EmailField<span class=\"p\">()</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>name\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Entry</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    blog <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Blog<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    headline <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">255</span><span class=\"p\">)</span>\n    body_text <span class=\"o\">=</span> models<span class=\"o\">.</span>TextField<span class=\"p\">()</span>\n    pub_date <span class=\"o\">=</span> models<span class=\"o\">.</span>DateField<span class=\"p\">()</span>\n    mod_date <span class=\"o\">=</span> models<span class=\"o\">.</span>DateField<span class=\"p\">(</span>default<span class=\"o\">=</span>date<span class=\"o\">.</span>today<span class=\"p\">)</span>\n    authors <span class=\"o\">=</span> models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span>Author<span class=\"p\">)</span>\n    number_of_comments <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n    number_of_pingbacks <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n    rating <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>headline\n</code></pre></div>\n<section id=\"creating-objects\">\n<h2>创建对象<a class=\"heading-anchor\" href=\"#creating-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>为了用 Python 对象展示数据表对象，Django 使用了一套直观的系统：一个模型类代表一张数据表，一个模型类的实例代表数据库表中的一行记录。</p>\n<p>要创建一个对象，用关键字参数初始化它，然后调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 将其存入数据库。</p>\n<p>假设模型位于 Django 应用 <code class=\"docutils literal notranslate\">blog</code> 内的 <code class=\"docutils literal notranslate\">models.py</code> 文件中，以下是一个示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">blog.models</span> <span class=\"kn\">import</span> Blog\n<span class=\"gp\">&gt;&gt;&gt; </span>b <span class=\"o\">=</span> Blog<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Beatles Blog&quot;</span><span class=\"p\">,</span> tagline<span class=\"o\">=</span><span class=\"s2\">&quot;All the latest Beatles news.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>这在幕后执行了 <code class=\"docutils literal notranslate\">INSERT</code> SQL 语句。Django 在你显式调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 才操作数据库。</p>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 方法没有返回值。</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">See also</p>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 接受很多此处未介绍的高级选项。参考文档 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 获取完整细节。</p>\n<p>To create and save an object in a single step, use the\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.create\" title=\"django.db.models.query.QuerySet.create\"><code class=\"xref py py-meth docutils literal notranslate\">create()</code></a> method.</p>\n</aside>\n</section>\n<section id=\"saving-changes-to-objects\">\n<h2>将修改保存至对象<a class=\"heading-anchor\" href=\"#saving-changes-to-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>要将修改保存至数据库中已有的某个对象，使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a>。</p>\n<p>给定一个已经保存到数据库中的 <code class=\"docutils literal notranslate\">Blog</code> 实例 <code class=\"docutils literal notranslate\">b5</code>，这个示例会修改其名称并更新其在数据库中的记录：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>b5<span class=\"o\">.</span>name <span class=\"o\">=</span> <span class=\"s2\">&quot;New name&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b5<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>这在幕后执行了 <code class=\"docutils literal notranslate\">UPDATE</code> SQL 语句。Django 在你显示调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 后才操作数据库。</p>\n<section id=\"saving-foreignkey-and-manytomanyfield-fields\">\n<h3>保存 <code class=\"docutils literal notranslate\">ForeignKey</code> 和 <code class=\"docutils literal notranslate\">ManyToManyField</code> 字段<a class=\"heading-anchor\" href=\"#saving-foreignkey-and-manytomanyfield-fields\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>更新 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 字段的方法与保存普通字段完全相同——将正确类型的对象分配给相应的字段。这个示例更新了 <code class=\"docutils literal notranslate\">Entry</code> 实例 <code class=\"docutils literal notranslate\">entry</code> 的 <code class=\"docutils literal notranslate\">blog</code> 属性，假设已经保存了适当的 <code class=\"docutils literal notranslate\">Entry</code> 和 <code class=\"docutils literal notranslate\">Blog</code> 实例到数据库中（因此我们可以在下面检索到它们）：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">blog.models</span> <span class=\"kn\">import</span> Blog<span class=\"p\">,</span> Entry\n<span class=\"gp\">&gt;&gt;&gt; </span>entry <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>cheese_blog <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Cheddar Talk&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>entry<span class=\"o\">.</span>blog <span class=\"o\">=</span> cheese_blog\n<span class=\"gp\">&gt;&gt;&gt; </span>entry<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>更新 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> 有一些不同之处——可以使用字段上的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/relations/#django.db.models.fields.related.RelatedManager.add\" title=\"django.db.models.fields.related.RelatedManager.add\"><code class=\"xref py py-meth docutils literal notranslate\">add()</code></a> 方法来添加一个记录到关系中。这个示例将 <code class=\"docutils literal notranslate\">Author</code> 实例 <code class=\"docutils literal notranslate\">joe</code> 添加到 <code class=\"docutils literal notranslate\">entry</code> 对象中：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">blog.models</span> <span class=\"kn\">import</span> Author\n<span class=\"gp\">&gt;&gt;&gt; </span>joe <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Joe&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>entry<span class=\"o\">.</span>authors<span class=\"o\">.</span>add<span class=\"p\">(</span>joe<span class=\"p\">)</span>\n</code></pre></div>\n<p>要一次性添加多个记录到 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a>，在调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/relations/#django.db.models.fields.related.RelatedManager.add\" title=\"django.db.models.fields.related.RelatedManager.add\"><code class=\"xref py py-meth docutils literal notranslate\">add()</code></a> 时包括多个参数，如下所示：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>john <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;John&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>paul <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Paul&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>george <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;George&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>ringo <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Ringo&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>entry<span class=\"o\">.</span>authors<span class=\"o\">.</span>add<span class=\"p\">(</span>john<span class=\"p\">,</span> paul<span class=\"p\">,</span> george<span class=\"p\">,</span> ringo<span class=\"p\">)</span>\n</code></pre></div>\n<p>Django 会在添加或指定错误类型的对象时报错。</p>\n</section>\n</section>\n<section id=\"retrieving-objects\">\n<span id=\"id1\"></span><h2>检索对象<a class=\"heading-anchor\" href=\"#retrieving-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>要从数据库检索对象，要通过模型类的 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> 构建一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>。</p>\n<p>一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 代表来自数据库中对象的一个集合。它可以有 0 个，1 个或者多个 <em>filters</em>. Filters，可以根据给定参数缩小查询结果量。在 SQL 的层面上， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 对应 <code class=\"docutils literal notranslate\">SELECT</code> 语句，而*filters*对应类似 <code class=\"docutils literal notranslate\">WHERE</code> 或 <code class=\"docutils literal notranslate\">LIMIT</code> 的限制子句。</p>\n<p>通过使用你的模型的 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a>，你可以获得一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>。每个模型至少有一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a>，默认情况下称为 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/class/#django.db.models.Model.objects\" title=\"django.db.models.Model.objects\"><code class=\"xref py py-attr docutils literal notranslate\">objects</code></a>。可以直接通过模型类来访问它，如下所示：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects\n<span class=\"go\">&lt;django.db.models.manager.Manager object at ...&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b <span class=\"o\">=</span> Blog<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Foo&quot;</span><span class=\"p\">,</span> tagline<span class=\"o\">=</span><span class=\"s2\">&quot;Bar&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>objects\n<span class=\"go\">Traceback:</span>\n<span class=\"go\">    ...</span>\n<span class=\"go\">AttributeError: &quot;Manager isn&#39;t accessible via Blog instances.&quot;</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>A <code class=\"docutils literal notranslate\">Manager</code> is accessible only via model classes, rather than from model\ninstances, to enforce a separation between &quot;table-level&quot; operations and\n&quot;record-level&quot; operations.</p>\n</aside>\n<p>The <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> is the main source of querysets for\na model. For example, <code class=\"docutils literal notranslate\">Blog.objects.all()</code> returns a\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> that contains all <code class=\"docutils literal notranslate\">Blog</code> objects in\nthe database.</p>\n<section id=\"retrieving-all-objects\">\n<h3>检索全部对象<a class=\"heading-anchor\" href=\"#retrieving-all-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>从表中检索对象的最简单方法是获取所有对象。要做到这一点，可以在 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> 上使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.all\" title=\"django.db.models.query.QuerySet.all\"><code class=\"xref py py-meth docutils literal notranslate\">all()</code></a> 方法：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>all_entries <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n</code></pre></div>\n<p>方法 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.all\" title=\"django.db.models.query.QuerySet.all\"><code class=\"xref py py-meth docutils literal notranslate\">all()</code></a> 返回了一个包含数据库中所有对象的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 对象。</p>\n</section>\n<section id=\"retrieving-specific-objects-with-filters\">\n<h3>通过过滤器检索指定对象<a class=\"heading-anchor\" href=\"#retrieving-specific-objects-with-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.all\" title=\"django.db.models.query.QuerySet.all\"><code class=\"xref py py-meth docutils literal notranslate\">all()</code></a> 返回的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 包含了数据表中所有的对象。虽然，大多数情况下，你只需要完整对象集合的一个子集。</p>\n<p>要创建一个这样的子集，你需要通过添加过滤条件精炼原始 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>。两种最常见的精炼 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 的方式是：</p>\n<dl class=\"simple\">\n<dt><code class=\"docutils literal notranslate\">filter(**kwargs)</code></dt><dd><p>返回一个新的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，包含的对象满足给定查询参数。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\">exclude(**kwargs)</code></dt><dd><p>返回一个新的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，包含的对象 <em>不</em> 满足给定查询参数。</p>\n</dd>\n</dl>\n<p>查询参数（<code class=\"docutils literal notranslate\">**kwargs</code>）应该符合下面的 <a class=\"reference internal\" href=\"#field-lookups\">Field lookups</a> 的要求。</p>\n<p>例如，要包含获取 2006 年的博客条目（entries blog）的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，像这样使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__year<span class=\"o\">=</span><span class=\"mi\">2006</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>通过默认管理器类也一样:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__year<span class=\"o\">=</span><span class=\"mi\">2006</span><span class=\"p\">)</span>\n</code></pre></div>\n<section id=\"chaining-filters\">\n<span id=\"id2\"></span><h4>链式过滤器<a class=\"heading-anchor\" href=\"#chaining-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>对 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 进行细化的结果本身也是一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，因此可以将细化操作链接在一起。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>headline__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;What&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>exclude<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    pub_date__gte<span class=\"o\">=</span>datetime<span class=\"o\">.</span>date<span class=\"o\">.</span>today<span class=\"p\">()</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__gte<span class=\"o\">=</span>datetime<span class=\"o\">.</span>date<span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>这个先获取包含数据库所有条目（entry）的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，然后排除一些，再进入另一个过滤器。最终的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 包含标题以 &quot;What&quot; 开头的，发布日期介于 2005 年 1 月 30 日与今天之间的所有条目。</p>\n</section>\n<section id=\"filtered-querysets-are-unique\">\n<span id=\"id3\"></span><h4>每个 <code class=\"docutils literal notranslate\">QuerySet</code> 都是唯一的<a class=\"heading-anchor\" href=\"#filtered-querysets-are-unique\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>每次你细化一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，都会得到一个新的、完全不受之前 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 影响的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>。每一次细化都创建了一个独立且不同的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，它可以被存储、使用和重复利用。</p>\n<p>例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>q1 <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>headline__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;What&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q2 <span class=\"o\">=</span> q1<span class=\"o\">.</span>exclude<span class=\"p\">(</span>pub_date__gte<span class=\"o\">=</span>datetime<span class=\"o\">.</span>date<span class=\"o\">.</span>today<span class=\"p\">())</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q3 <span class=\"o\">=</span> q1<span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__gte<span class=\"o\">=</span>datetime<span class=\"o\">.</span>date<span class=\"o\">.</span>today<span class=\"p\">())</span>\n</code></pre></div>\n<p>These three querysets are separate. The first is a base\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> containing all entries that contain a\nheadline starting with &quot;What&quot;. The second is a subset of the first, with an\nadditional criteria that excludes records whose <code class=\"docutils literal notranslate\">pub_date</code> is today or in the\nfuture. The third is a subset of the first, with an additional criteria that\nselects only the records whose <code class=\"docutils literal notranslate\">pub_date</code> is today or in the future. The\ninitial <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> (<code class=\"docutils literal notranslate\">q1</code>) is unaffected by the\nrefinement process.</p>\n</section>\n<section id=\"querysets-are-lazy\">\n<span id=\"id4\"></span><h4><code class=\"docutils literal notranslate\">QuerySet</code> 是惰性的<a class=\"heading-anchor\" href=\"#querysets-are-lazy\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\">QuerySet</code> objects are lazy -- the act of creating a\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> doesn't involve any database\nactivity. You can stack filters together all day long, and Django won't\nactually run the query until the <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> is\n<em>evaluated</em>. Take a look at this example:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>q <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>headline__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;What&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q <span class=\"o\">=</span> q<span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__lte<span class=\"o\">=</span>datetime<span class=\"o\">.</span>date<span class=\"o\">.</span>today<span class=\"p\">())</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q <span class=\"o\">=</span> q<span class=\"o\">.</span>exclude<span class=\"p\">(</span>body_text__icontains<span class=\"o\">=</span><span class=\"s2\">&quot;food&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>q<span class=\"p\">)</span>\n</code></pre></div>\n<p>虽然这看起来像是三次数据库操作，实际上只在最后一行 (<code class=\"docutils literal notranslate\">print(q)</code>) 做了一次。一般来说， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 的结果直到你 “要使用” 时才会从数据库中拿出。当你要用时，才通过数据库 <em>计算</em> 出 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>。关于何时才真的执行计算的更多细节，参考 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#when-querysets-are-evaluated\"><span class=\"std std-ref\">什么时候 QuerySet 被执行</span></a>。</p>\n</section>\n</section>\n<section id=\"retrieving-a-single-object-with-get\">\n<span id=\"retrieving-single-object-with-get\"></span><h3>用 <code class=\"docutils literal notranslate\">get()</code> 检索单个对象<a class=\"heading-anchor\" href=\"#retrieving-a-single-object-with-get\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a> 总是返回一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，即便只有一个对象满足查询条件 —— 这种情况下， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 只包含了一个元素。</p>\n<p>如果你知道只有一个对象符合你的查询条件，你可以在 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> 上使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a> 方法，它会直接返回该对象：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>one_entry <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>你可以对 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a> 使用与 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a> 类似的所有查询表达式 —— 同样的，参考下面的 <a class=\"reference internal\" href=\"#field-lookups\">Field lookups</a>。</p>\n<p>注意， 使用切片 <code class=\"docutils literal notranslate\">[0]</code> 时的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a> 有点不同。如果没有满足查询条件的结果， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a> 会抛出一个 <code class=\"docutils literal notranslate\">DoesNotExist</code> 异常。该异常是执行查询的模型类的一个属性 —— 所有，上述代码中，若没有哪个 <code class=\"docutils literal notranslate\">Entry</code> 对象的主键是 1，Django 会抛出 <code class=\"docutils literal notranslate\">Entry.DoesNotExist</code>。</p>\n<p>类似了，Django 会在有不止一个记录满足 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a> 查询条件时发出警告。这时，Django 会抛出 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/exceptions/#django.core.exceptions.MultipleObjectsReturned\" title=\"django.core.exceptions.MultipleObjectsReturned\"><code class=\"xref py py-exc docutils literal notranslate\">MultipleObjectsReturned</code></a>，这同样也是模型类的一个属性。</p>\n</section>\n<section id=\"other-queryset-methods\">\n<h3>其它 <code class=\"docutils literal notranslate\">QuerySet</code> 方法<a class=\"heading-anchor\" href=\"#other-queryset-methods\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>大多数情况下，你会在需要从数据库中检索对象时使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.all\" title=\"django.db.models.query.QuerySet.all\"><code class=\"xref py py-meth docutils literal notranslate\">all()</code></a>， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a>， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\">exclude()</code></a>。然而，这样远远不够；完整的各种 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 方法请参阅 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#queryset-api\"><span class=\"std std-ref\">QuerySet API 参考</span></a>。</p>\n</section>\n<section id=\"limiting-querysets\">\n<span id=\"id5\"></span><h3>限制 <code class=\"docutils literal notranslate\">QuerySet</code> 条目数<a class=\"heading-anchor\" href=\"#limiting-querysets\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>利用 Python 的数组切片语法将 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 切成指定长度。这等价于 SQL 的 <code class=\"docutils literal notranslate\">LIMIT</code> 和 <code class=\"docutils literal notranslate\">OFFSET</code> 子句。</p>\n<p>例如，这返回前5个对象（<code class=\"docutils literal notranslate\">LIMIT 5</code>）：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>这返回第六到第十个对象（<code class=\"docutils literal notranslate\">OFFSET 5 LIMIT 5</code>）：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()[</span><span class=\"mi\">5</span><span class=\"p\">:</span><span class=\"mi\">10</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>不支持负索引 (例如 <code class=\"docutils literal notranslate\">Entry.objects.all()[-1]</code>)</p>\n<p>通常，对 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 进行切片会返回一个新的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，它不会评估查询。一个例外是如果使用了 Python 切片语法的 &quot;step&quot; 参数。例如，这会实际执行查询，以返回前10个对象中的每 <em>第二个</em> 对象的列表：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()[:</span><span class=\"mi\">10</span><span class=\"p\">:</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>由于对 queryset 切片工作方式的模糊性，禁止对其进行进一步的排序或过滤。</p>\n<p>要检索 <em>单个</em> 对象而不是列表（例如，<code class=\"docutils literal notranslate\">SELECT foo FROM bar LIMIT 1</code>），请使用索引而不是切片。例如，这会按标题的字母顺序返回数据库中的第一个 <code class=\"docutils literal notranslate\">Entry</code>：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s2\">&quot;headline&quot;</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>这大致相当于：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s2\">&quot;headline&quot;</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">:</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span>get<span class=\"p\">()</span>\n</code></pre></div>\n<p>然而，注意一下，若没有对象满足给定条件，前者会抛出 <code class=\"docutils literal notranslate\">IndexError</code>，而后者会抛出 <code class=\"docutils literal notranslate\">DoesNotExist</code>。参考 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a> 获取更多细节。</p>\n</section>\n<section id=\"field-lookups\">\n<span id=\"field-lookups-intro\"></span><h3>字段查询<a class=\"heading-anchor\" href=\"#field-lookups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>字段查询即你如何制定 SQL <code class=\"docutils literal notranslate\">WHERE</code> 子句。它们以关键字参数的形式传递给 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 方法 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a>， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\">exclude()</code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a>。</p>\n<p>基本的查找关键字参数采用形式 <code class=\"docutils literal notranslate\">field__lookuptype=value</code> （使用双下划线）。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__lte<span class=\"o\">=</span><span class=\"s2\">&quot;2006-01-01&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>转换为 SQL 语句大致如下：</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span> <span class=\"o\">*</span> <span class=\"k\">FROM</span> blog_entry <span class=\"k\">WHERE</span> pub_date <span class=\"o\">&lt;=</span> <span class=\"s1\">&#39;2006-01-01&#39;</span><span class=\"p\">;</span>\n</code></pre></div>\n<aside class=\"admonition-how-this-is-possible admonition\" role=\"note\">\n<p class=\"admonition-title\">这是怎么做到的</p>\n<p>Python 能定义可接受任意数量 name-value 参数的函数，参数名和值均在运行时计算。更多信息，请参考官方 Python 教程中的 <a class=\"reference external\" href=\"https://docs.python.org/3/tutorial/controlflow.html#tut-keywordargs\" title=\"(in Python v3.14)\"><span>Keyword Arguments</span></a>。</p>\n</aside>\n<p>查询子句中指定的字段必须是模型的一个字段名。不过也有个例外，在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 中，你可以指定以 <code class=\"docutils literal notranslate\">_id</code> 为后缀的字段名。这种情况下，value 参数需要包含 foreign 模型的主键的原始值。例子：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog_id<span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>若你传入了无效的关键字参数，查询函数会抛出 <code class=\"docutils literal notranslate\">TypeError</code>。</p>\n<p>数据库 API 支持两套查询类型；完整参考文档位于 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#field-lookups\"><span class=\"std std-ref\">字段查询参考</span></a>。为了让你了解能干啥，以下是一些常见的查询：</p>\n<dl>\n<dt><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-exact\"><code class=\"xref std std-lookup docutils literal notranslate\">exact</code></a></dt><dd><p>一个 &quot;exact&quot; 匹配。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>headline__exact<span class=\"o\">=</span><span class=\"s2\">&quot;Cat bites dog&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>会生成这些 SQL：</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span> <span class=\"p\">...</span> <span class=\"k\">WHERE</span> headline <span class=\"o\">=</span> <span class=\"s1\">&#39;Cat bites dog&#39;</span><span class=\"p\">;</span>\n</code></pre></div>\n<p>若你未提供查询类型 —— 也就说，若关键字参数未包含双下划线 —— 查询类型会被指定为 <code class=\"docutils literal notranslate\">exact</code>。</p>\n<p>例如，以下两个语句是等价的：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>id__exact<span class=\"o\">=</span><span class=\"mi\">14</span><span class=\"p\">)</span>  <span class=\"c1\"># Explicit form</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">14</span><span class=\"p\">)</span>  <span class=\"c1\"># __exact is implied</span>\n</code></pre></div>\n<p>这是为了方便，因为 <code class=\"docutils literal notranslate\">exact</code> 查询是最常见的。</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-iexact\"><code class=\"xref std std-lookup docutils literal notranslate\">iexact</code></a></dt><dd><p>不区分大小写的匹配。因此，查询：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>name__iexact<span class=\"o\">=</span><span class=\"s2\">&quot;beatles blog&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>会匹配标题为 <code class=\"docutils literal notranslate\">&quot;Beatles Blog&quot;</code>， <code class=\"docutils literal notranslate\">&quot;beatles blog&quot;</code>， 甚至 <code class=\"docutils literal notranslate\">&quot;BeAtlES blOG&quot;</code> 的 <code class=\"docutils literal notranslate\">Blog</code>。</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-contains\"><code class=\"xref std std-lookup docutils literal notranslate\">contains</code></a></dt><dd><p>大小写敏感的包含测试。例子:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>粗略地转为 SQL：</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span> <span class=\"p\">...</span> <span class=\"k\">WHERE</span> headline <span class=\"k\">LIKE</span> <span class=\"s1\">&#39;%Lennon%&#39;</span><span class=\"p\">;</span>\n</code></pre></div>\n<p>注意这将匹配标题 <code class=\"docutils literal notranslate\">'Today Lennon honored'</code>，而不是 <code class=\"docutils literal notranslate\">'today lennon honored'</code>。</p>\n<p>这也有个大小写不敏感的版本， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-icontains\"><code class=\"xref std std-lookup docutils literal notranslate\">icontains</code></a>。</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-startswith\"><code class=\"xref std std-lookup docutils literal notranslate\">startswith</code></a>, <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-endswith\"><code class=\"xref std std-lookup docutils literal notranslate\">endswith</code></a></dt><dd><p>以……开头和以……结尾的查找。当然也有大小写不敏感的版本，名为 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-istartswith\"><code class=\"xref std std-lookup docutils literal notranslate\">istartswith</code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-iendswith\"><code class=\"xref std std-lookup docutils literal notranslate\">iendswith</code></a>。</p>\n</dd>\n</dl>\n<p>同样，这只介绍了皮毛。完整的参考能在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#field-lookups\"><span class=\"std std-ref\">field 查询参考</span></a> 找到。</p>\n</section>\n<section id=\"lookups-that-span-relationships\">\n<span id=\"id6\"></span><h3>跨关系查询<a class=\"heading-anchor\" href=\"#lookups-that-span-relationships\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 提供了一种强大而直观的方式来“追踪”查询中的关系，在幕后自动为你处理 SQL <code class=\"docutils literal notranslate\">JOIN</code> 关系。为了跨越关系，跨模型使用关联字段名，字段名由双下划线分割，直到拿到想要的字段。</p>\n<p>这个示例检索所有具有 <code class=\"docutils literal notranslate\">name</code> 为 <code class=\"docutils literal notranslate\">'Beatles Blog'</code> 的 <code class=\"docutils literal notranslate\">Blog</code> 的 <code class=\"docutils literal notranslate\">Entry</code> 对象：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog__name<span class=\"o\">=</span><span class=\"s2\">&quot;Beatles Blog&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>跨域的深度随你所想。</p>\n<p>It works backwards, too. While it can be customized by setting\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey.related_query_name\" title=\"django.db.models.ForeignKey.related_query_name\"><code class=\"xref py py-class docutils literal notranslate\">related_query_name</code></a>, by default you\nrefer to a &quot;reverse&quot; relationship in a lookup using the lowercase name of the\nmodel.</p>\n<p>这个示例检索所有至少有一个 <code class=\"docutils literal notranslate\">headline</code> 包含 <code class=\"docutils literal notranslate\">'Lennon'</code> 的 <code class=\"docutils literal notranslate\">Entry</code> 的 <code class=\"docutils literal notranslate\">Blog</code> 对象：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>entry__headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>如果你在跨多个关系进行筛选，而某个中间模型的没有满足筛选条件的值，Django  会将它当做一个空的（所有值都是 <code class=\"docutils literal notranslate\">NULL</code>）但是有效的对象。这样就意味着不会抛出错误。例如，在这个过滤器中:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>entry__authors__name<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>（假设有个关联的 <code class=\"docutils literal notranslate\">Author</code> 模型），若某项条目没有任何关联的 <code class=\"docutils literal notranslate\">author</code>，它会被视作没有关联的 <code class=\"docutils literal notranslate\">name</code>，而不是因为缺失 <code class=\"docutils literal notranslate\">author</code> 而抛出错误。大多数情况下，这就是你期望的。唯一可能使你迷惑的场景是在使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-isnull\"><code class=\"xref std std-lookup docutils literal notranslate\">isnull</code></a> 时。因此:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>entry__authors__name__isnull<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>将会返回 <code class=\"docutils literal notranslate\">Blog</code> 对象，包含 <code class=\"docutils literal notranslate\">author</code> 的 <code class=\"docutils literal notranslate\">name</code> 为空的对象，以及那些 <code class=\"docutils literal notranslate\">entry</code> 的 <code class=\"docutils literal notranslate\">author</code> 为空的对象。若你不想要后面的对象，你可以这样写:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>entry__authors__isnull<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> entry__authors__name__isnull<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n<section id=\"spanning-multi-valued-relationships\">\n<span id=\"id7\"></span><h4>跨多值关联<a class=\"heading-anchor\" href=\"#spanning-multi-valued-relationships\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>当跨越 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> 或反查 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> （例如从 <code class=\"docutils literal notranslate\">Blog</code> 到 <code class=\"docutils literal notranslate\">Entry</code> ）时，对多个属性进行过滤会产生这样的问题：是否要求每个属性都在同一个相关对象中重合。我们可能会寻找那些在标题中含有 <em>“Lennon”</em> 的 2008 年的博客，或者我们可能会寻找那些仅有 2008 年的任何条目以及一些在标题中含有 <em>“Lennon”</em> 的较新或较早的条目。</p>\n<p>要选择所有包含 2008 年至少一个标题中有 <em>&quot;Lennon&quot;</em> 的条目的博客（满足两个条件的同一条目），我们要写：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>entry__headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">,</span> entry__pub_date__year<span class=\"o\">=</span><span class=\"mi\">2008</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>否则，如果要执行一个更为宽松的查询，选择任何只在标题中带有 <em>&quot;Lennon&quot;</em> 的条目和 2008 年的条目的博客，我们将写：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>entry__headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>\n    entry__pub_date__year<span class=\"o\">=</span><span class=\"mi\">2008</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>假设只有一个博客既有包含 <em>&quot;Lennon&quot;</em> 的条目又有 2008 年的条目，但 2008 年的条目中没有包含 <em>&quot;Lennon&quot;</em> 。第一个查询不会返回任何博客，但第二个查询会返回那一个博客。（这是因为第二个过滤器选择的条目可能与第一个过滤器中的条目相同，也可能不相同）。我们是用每个过滤器语句来过滤 <code class=\"docutils literal notranslate\">Blog</code> 项，而不是 <code class=\"docutils literal notranslate\">Entry</code> 项）。简而言之，如果每个条件需要匹配相同的相关对象，那么每个条件应该包含在一个 <code class=\"xref py py-meth docutils literal notranslate\">filter()</code> 调用中。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>由于第二个（更宽松的）查询链接了多个过滤器，它对主模型进行了多次连接，可能会产生重复的结果。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">datetime</span> <span class=\"kn\">import</span> date\n<span class=\"gp\">&gt;&gt;&gt; </span>beatles <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Beatles Blog&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>pop <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Pop Music Blog&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    blog<span class=\"o\">=</span>beatles<span class=\"p\">,</span>\n<span class=\"gp\">... </span>    headline<span class=\"o\">=</span><span class=\"s2\">&quot;New Lennon Biography&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Entry: New Lennon Biography&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    blog<span class=\"o\">=</span>beatles<span class=\"p\">,</span>\n<span class=\"gp\">... </span>    headline<span class=\"o\">=</span><span class=\"s2\">&quot;New Lennon Biography in Paperback&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2009</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Entry: New Lennon Biography in Paperback&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    blog<span class=\"o\">=</span>pop<span class=\"p\">,</span>\n<span class=\"gp\">... </span>    headline<span class=\"o\">=</span><span class=\"s2\">&quot;Best Albums of 2008&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">15</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Entry: Best Albums of 2008&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    blog<span class=\"o\">=</span>pop<span class=\"p\">,</span>\n<span class=\"gp\">... </span>    headline<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon Would Have Loved Hip Hop&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2020</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Entry: Lennon Would Have Loved Hip Hop&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    entry__headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    entry__pub_date__year<span class=\"o\">=</span><span class=\"mi\">2008</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Blog: Beatles Blog&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    entry__headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    entry__pub_date__year<span class=\"o\">=</span><span class=\"mi\">2008</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Blog: Beatles Blog&gt;, &lt;Blog: Beatles Blog&gt;, &lt;Blog: Pop Music Blog]&gt;</span>\n</code></pre></div>\n</aside>\n<aside class=\"admonition admonition-note\" id=\"exclude-implementation\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a> 的查询行为会跨越多值关联，就像前文说的那样，并不与 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\">exclude()</code></a> 相同。相反，一次 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\">exclude()</code></a> 调用的条件并不需要指向同一项目。</p>\n<p>例如，以下查询会排除那些关联条目标题包含 <em>&quot;Lennon&quot;</em> 且发布于 2008 年的博客:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>exclude<span class=\"p\">(</span>\n    entry__headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">,</span>\n    entry__pub_date__year<span class=\"o\">=</span><span class=\"mi\">2008</span><span class=\"p\">,</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>但是，与 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a> 的行为不同，其并不会限制博客同时满足这两种条件。要这么做的话，也就是筛选出所有条目标题不带 <em>&quot;Lennon&quot;</em> 且发布年不是 2008 的博客，你需要做两次查询:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>exclude<span class=\"p\">(</span>\n    entry__in<span class=\"o\">=</span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n        headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">,</span>\n        pub_date__year<span class=\"o\">=</span><span class=\"mi\">2008</span><span class=\"p\">,</span>\n    <span class=\"p\">),</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n</aside>\n</section>\n</section>\n<section id=\"filters-can-reference-fields-on-the-model\">\n<span id=\"using-f-expressions-in-filters\"></span><h3>过滤器可以为模型指定字段<a class=\"heading-anchor\" href=\"#filters-can-reference-fields-on-the-model\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>在之前的例子中，我们已经构建过的 <code class=\"docutils literal notranslate\">filter</code> 都是将模型字段值与常量做比较。但是，要怎么做才能将模型字段值与同一模型中的另一字段做比较呢？</p>\n<p>Django provides <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/expressions/#f-expressions\"><span class=\"std std-ref\">F() 表达式</span></a> to allow such comparisons. Instances of\n<code class=\"docutils literal notranslate\">F()</code> act as a reference to a model field within a query. These references\ncan then be used in query filters to compare the values of two different fields\non the same model instance.</p>\n<p>例如，要找到所有具有比 pingback 更多评论的博客条目的列表，我们构建一个引用 pingback 计数的 <code class=\"docutils literal notranslate\">F()</code> 对象，并在查询中使用该 <code class=\"docutils literal notranslate\">F()</code> 对象：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> F\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>number_of_comments__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;number_of_pingbacks&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Django 支持在 <code class=\"docutils literal notranslate\">F()</code> 对象中使用加法、减法、乘法、除法、取模和幂算术，既可以与常数一起使用，也可以与其他 <code class=\"docutils literal notranslate\">F()</code> 对象一起使用。要查找所有具有评论数超过 pingback 两倍的博客条目，我们修改查询如下：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>number_of_comments__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;number_of_pingbacks&quot;</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>要查找所有评分低于评论数和 pingback 数的总和的条目，我们可以发出以下查询：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>rating__lt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;number_of_comments&quot;</span><span class=\"p\">)</span> <span class=\"o\">+</span> F<span class=\"p\">(</span><span class=\"s2\">&quot;number_of_pingbacks&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>你还可以在 <code class=\"docutils literal notranslate\">F()</code> 对象中使用双下划线符号来跨越关系。带有双下划线的 <code class=\"docutils literal notranslate\">F()</code> 对象将引入任何所需的连接以访问相关对象。例如，要检索所有作者名称与博客名称相同的条目，可以发出以下查询：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>authors__name<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;blog__name&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>对于日期和日期/时间字段，你可以添加或减去一个 <a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.timedelta\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">timedelta</code></a> 对象。以下代码将返回所有在发布后超过3天修改的条目：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">datetime</span> <span class=\"kn\">import</span> timedelta\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>mod_date__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">)</span> <span class=\"o\">+</span> timedelta<span class=\"p\">(</span>days<span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">))</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">F()</code> 对象支持位操作，包括 <code class=\"docutils literal notranslate\">.bitand()</code>、<code class=\"docutils literal notranslate\">.bitor()</code>、<code class=\"docutils literal notranslate\">.bitxor()</code>、<code class=\"docutils literal notranslate\">.bitrightshift()</code> 和 <code class=\"docutils literal notranslate\">.bitleftshift()</code>。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>F<span class=\"p\">(</span><span class=\"s2\">&quot;somefield&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>bitand<span class=\"p\">(</span><span class=\"mi\">16</span><span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition-oracle admonition\" role=\"note\">\n<p class=\"admonition-title\">Oracle</p>\n<p>Oracle 不支持按位 XOR 操作。</p>\n</aside>\n</section>\n<section id=\"expressions-can-reference-transforms\">\n<span id=\"using-transforms-in-expressions\"></span><h3>表达式可以引用变换<a class=\"heading-anchor\" href=\"#expressions-can-reference-transforms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 支持在表达式中使用变换。</p>\n<p>例如，要找到所有与它们上次修改的年份相同的 <code class=\"docutils literal notranslate\">Entry</code> 对象：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> F\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__year<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;mod_date__year&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>要找到条目发布的最早年份，我们可以发出以下查询：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Min\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>aggregate<span class=\"p\">(</span>first_published_year<span class=\"o\">=</span>Min<span class=\"p\">(</span><span class=\"s2\">&quot;pub_date__year&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>这个示例查找了评分最高的条目的值以及每年所有条目的总评论数：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> OuterRef<span class=\"p\">,</span> Subquery<span class=\"p\">,</span> Sum\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>values<span class=\"p\">(</span><span class=\"s2\">&quot;pub_date__year&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    top_rating<span class=\"o\">=</span>Subquery<span class=\"p\">(</span>\n<span class=\"gp\">... </span>        Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"gp\">... </span>            pub_date__year<span class=\"o\">=</span>OuterRef<span class=\"p\">(</span><span class=\"s2\">&quot;pub_date__year&quot;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>        <span class=\"p\">)</span>\n<span class=\"gp\">... </span>        <span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s2\">&quot;-rating&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>        <span class=\"o\">.</span>values<span class=\"p\">(</span><span class=\"s2\">&quot;rating&quot;</span><span class=\"p\">)[:</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n<span class=\"gp\">... </span>    <span class=\"p\">),</span>\n<span class=\"gp\">... </span>    total_comments<span class=\"o\">=</span>Sum<span class=\"p\">(</span><span class=\"s2\">&quot;number_of_comments&quot;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"the-pk-lookup-shortcut\">\n<h3>主键 (<code class=\"docutils literal notranslate\">pk</code>) 查询快捷方式<a class=\"heading-anchor\" href=\"#the-pk-lookup-shortcut\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>出于方便的目的，Django 提供了一种 <code class=\"docutils literal notranslate\">pk</code> 查询快捷方式， <code class=\"docutils literal notranslate\">pk</code> 表示主键 &quot;primary key&quot;。</p>\n<p>在示例的 <code class=\"docutils literal notranslate\">Blog</code> 模型中，主键是 <code class=\"docutils literal notranslate\">id</code> 字段，因此以下三个语句是等效的：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>id__exact<span class=\"o\">=</span><span class=\"mi\">14</span><span class=\"p\">)</span>  <span class=\"c1\"># Explicit form</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">14</span><span class=\"p\">)</span>  <span class=\"c1\"># __exact is implied</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">14</span><span class=\"p\">)</span>  <span class=\"c1\"># pk implies id__exact</span>\n</code></pre></div>\n<p>对于 <code class=\"docutils literal notranslate\">pk</code> 的使用不限于 <code class=\"docutils literal notranslate\">__exact</code> 查询 —— 任何查询条件都可以与 <code class=\"docutils literal notranslate\">pk</code> 结合使用，以执行关于模型的主键的查询：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"go\"># Get blogs entries with id 1, 4 and 7</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pk__in<span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">])</span>\n\n<span class=\"go\"># Get all blog entries with id &gt; 14</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pk__gt<span class=\"o\">=</span><span class=\"mi\">14</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">pk</code> 查询也可以跨越关联进行。例如，以下三个语句是等效的：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog__id__exact<span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">)</span>  <span class=\"c1\"># Explicit form</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog__id<span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">)</span>  <span class=\"c1\"># __exact is implied</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog__pk<span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">)</span>  <span class=\"c1\"># __pk implies __id__exact</span>\n</code></pre></div>\n</section>\n<section id=\"escaping-percent-signs-and-underscores-in-like-statements\">\n<h3>在 <code class=\"docutils literal notranslate\">LIKE</code> 语句中转义百分号和下划线<a class=\"heading-anchor\" href=\"#escaping-percent-signs-and-underscores-in-like-statements\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>等效于 <code class=\"docutils literal notranslate\">LIKE</code> SQL 语句的字段查询子句 (<code class=\"docutils literal notranslate\">iexact</code>， <code class=\"docutils literal notranslate\">contains</code>， <code class=\"docutils literal notranslate\">icontains</code>， <code class=\"docutils literal notranslate\">startswith</code>， <code class=\"docutils literal notranslate\">istartswith</code>， <code class=\"docutils literal notranslate\">endswith</code> 和 <code class=\"docutils literal notranslate\">iendswith</code>) 会将 <code class=\"docutils literal notranslate\">LIKE</code> 语句中有特殊用途的两个符号，即百分号和下划线自动转义。（在 <code class=\"docutils literal notranslate\">LIKE</code> 语句中，百分号匹配多个任意字符，而下划线匹配一个任意字符。）</p>\n<p>这意味着事情应该工作得很直观，所以抽象不会泄露。例如，要检索所有包含百分号的条目，可以将百分号视为任何其他字符：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;%&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Django 为你小心处理了引号；生成的 SQL 语句看起来像这样：</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span> <span class=\"p\">...</span> <span class=\"k\">WHERE</span> headline <span class=\"k\">LIKE</span> <span class=\"s1\">&#39;%\\%%&#39;</span><span class=\"p\">;</span>\n</code></pre></div>\n<p>同样的处理也包括下划线。百分号和下划线都为你自动处理，你无需担心。</p>\n</section>\n<section id=\"caching-and-querysets\">\n<span id=\"id8\"></span><h3>缓存和 <code class=\"docutils literal notranslate\">QuerySet</code><a class=\"heading-anchor\" href=\"#caching-and-querysets\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>每个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 都带有缓存，尽量减少数据库访问。理解它是如何工作的能让你编写更高效的代码。</p>\n<p>新创建的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 缓存是空的。一旦要计算 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 的值，就会执行数据查询，随后，Django 就会将查询结果保存在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 的缓存中，并返回这些显式请求的缓存（例如，下一个元素，若 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 正在被迭代）。后续针对 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 的计算会复用缓存结果。</p>\n<p>请记住这种缓存行为，因为如果不正确使用你的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，可能会出现问题。例如，以下代码会创建两个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，对它们进行评估，然后将它们丢弃：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">([</span>e<span class=\"o\">.</span>headline <span class=\"k\">for</span> e <span class=\"ow\">in</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()])</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">([</span>e<span class=\"o\">.</span>pub_date <span class=\"k\">for</span> e <span class=\"ow\">in</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()])</span>\n</code></pre></div>\n<p>这意味着同样的数据库查询会被执行两次，实际加倍了数据库负载。同时，有可能这两个列表不包含同样的记录，因为在两次请求间，可能有 <code class=\"docutils literal notranslate\">Entry</code> 被添加或删除了。</p>\n<p>为了避免这个问题，保存 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 并重复使用它：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>queryset <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">([</span>p<span class=\"o\">.</span>headline <span class=\"k\">for</span> p <span class=\"ow\">in</span> queryset<span class=\"p\">])</span>  <span class=\"c1\"># Evaluate the query set.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">([</span>p<span class=\"o\">.</span>pub_date <span class=\"k\">for</span> p <span class=\"ow\">in</span> queryset<span class=\"p\">])</span>  <span class=\"c1\"># Reuse the cache from the evaluation.</span>\n</code></pre></div>\n<section id=\"when-querysets-are-not-cached\">\n<h4>当 <code class=\"docutils literal notranslate\">QuerySet</code> 未被缓存时<a class=\"heading-anchor\" href=\"#when-querysets-are-not-cached\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Querysets do not always cache their results. When evaluating only <em>part</em> of\nthe queryset, the cache is checked, but if it is not populated then the items\nreturned by the subsequent query are not cached. Specifically, this means that\n<a class=\"reference internal\" href=\"#limiting-querysets\"><span class=\"std std-ref\">limiting the queryset</span></a> using an array slice or an\nindex will not populate the cache.</p>\n<p>例如，反复获取查询集对象中的某个索引会每次查询数据库：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>queryset <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>queryset<span class=\"p\">[</span><span class=\"mi\">5</span><span class=\"p\">])</span>  <span class=\"c1\"># Queries the database</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>queryset<span class=\"p\">[</span><span class=\"mi\">5</span><span class=\"p\">])</span>  <span class=\"c1\"># Queries the database again</span>\n</code></pre></div>\n<p>然而，如果整个查询集已经被评估过，那么会检查缓存而不是查询数据库：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>queryset <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">[</span>entry <span class=\"k\">for</span> entry <span class=\"ow\">in</span> queryset<span class=\"p\">]</span>  <span class=\"c1\"># Queries the database</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>queryset<span class=\"p\">[</span><span class=\"mi\">5</span><span class=\"p\">])</span>  <span class=\"c1\"># Uses cache</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>queryset<span class=\"p\">[</span><span class=\"mi\">5</span><span class=\"p\">])</span>  <span class=\"c1\"># Uses cache</span>\n</code></pre></div>\n<p>以下是一些其他会导致整个查询集被评估并因此填充缓存的示例操作：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">[</span>entry <span class=\"k\">for</span> entry <span class=\"ow\">in</span> queryset<span class=\"p\">]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">bool</span><span class=\"p\">(</span>queryset<span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>entry <span class=\"ow\">in</span> queryset\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">list</span><span class=\"p\">(</span>queryset<span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>只是打印查询结果集不会填充缓存。因为调用 <code class=\"docutils literal notranslate\">__repr__()</code> 仅返回了完整结果集的一个切片。</p>\n</aside>\n</section>\n</section>\n</section>\n<section id=\"asynchronous-queries\">\n<span id=\"async-queries\"></span><h2>异步查询<a class=\"heading-anchor\" href=\"#asynchronous-queries\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>如果你正在编写异步视图或代码，你不能像我们上面描述的那样完全使用 ORM 进行查询，因为你不能从异步代码中调用 <em>阻塞的</em> 同步代码 —— 它会阻塞事件循环（或者更可能的是，Django 会注意到并引发 <code class=\"docutils literal notranslate\">SynchronousOnlyOperation</code> 以阻止发生这种情况）。</p>\n<p>幸运的是，你可以使用 Django 的异步查询 API 执行许多查询。每个可能阻塞的方法，比如 <code class=\"docutils literal notranslate\">get()</code> 或 <code class=\"docutils literal notranslate\">delete()</code>，都有一个异步的变体（<code class=\"docutils literal notranslate\">aget()</code> 或 <code class=\"docutils literal notranslate\">adelete()</code>），当你遍历结果时，你可以使用异步迭代（<code class=\"docutils literal notranslate\">async for</code>）。</p>\n<section id=\"query-iteration\">\n<h3>查询迭代<a class=\"heading-anchor\" href=\"#query-iteration\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>默认情况下，通过 <code class=\"docutils literal notranslate\">for</code> 遍历查询会在幕后导致阻塞的数据库查询，因为 Django 在迭代时加载结果。要解决这个问题，你可以切换到 <code class=\"docutils literal notranslate\">async for</code>：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">for</span> entry <span class=\"ow\">in</span> Authors<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>name__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;A&quot;</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>请注意，你也不能执行其他可能会遍历查询集的操作，比如用 <code class=\"docutils literal notranslate\">list()</code> 包装它来强制评估它（如果需要，可以在推导式中使用 <code class=\"docutils literal notranslate\">async for</code>）。</p>\n<p>因为 <code class=\"docutils literal notranslate\">QuerySet</code> 方法，比如 <code class=\"docutils literal notranslate\">filter()</code> 和 <code class=\"docutils literal notranslate\">exclude()</code>，实际上不会运行查询 —— 它们设置了查询集，以便在迭代时运行 —— 所以你可以在异步代码中自由使用它们。关于哪些方法可以继续像这样使用，哪些有异步版本的指南，请阅读下一节。</p>\n</section>\n<section id=\"queryset-and-manager-methods\">\n<h3><code class=\"docutils literal notranslate\">QuerySet</code> 和管理器方法<a class=\"heading-anchor\" href=\"#queryset-and-manager-methods\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>管理器和查询集上的一些方法 - 比如 <code class=\"docutils literal notranslate\">get()</code> 和 <code class=\"docutils literal notranslate\">first()</code> - 强制执行查询集并会阻塞。而一些方法，比如 <code class=\"docutils literal notranslate\">filter()</code> 和 <code class=\"docutils literal notranslate\">exclude()</code>，不会强制执行查询集，因此可以从异步代码中安全运行。但是你应该如何区分它们呢？</p>\n<p>虽然你可以查看是否有方法的名称前缀是 <code class=\"docutils literal notranslate\">a</code> （例如，我们有 <code class=\"docutils literal notranslate\">aget()</code>，但没有 <code class=\"docutils literal notranslate\">afilter()</code>），但有一种更合理的方法是查看 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/\"><span class=\"doc\">QuerySet 参考文档</span></a>，了解方法的类型。</p>\n<p>在这里，你会发现查询集的方法分成了两个部分：</p>\n<ul class=\"simple\">\n<li><p><em>Methods that return new querysets</em>: These are the non-blocking ones,\nand don't have asynchronous versions. You're free to use these in any\nsituation, but understand the constraint of <a class=\"reference internal\" href=\"#no-deferred-queries\">no deferred queries</a> before\nusing <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.defer\" title=\"django.db.models.query.QuerySet.defer\"><code class=\"xref py py-meth docutils literal notranslate\">defer()</code></a>,\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.only\" title=\"django.db.models.query.QuerySet.only\"><code class=\"xref py py-meth docutils literal notranslate\">only()</code></a>, or\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.fetch_mode\" title=\"django.db.models.query.QuerySet.fetch_mode\"><code class=\"xref py py-meth docutils literal notranslate\">fetch_mode()</code></a>.</p></li>\n<li><p><em>不返回查询集的方法</em>：这些方法是阻塞的，并且有异步版本 - 在每个方法的文档中都有它的异步名称，尽管我们的标准模式是在名称前加上 <code class=\"docutils literal notranslate\">a</code> 前缀。</p></li>\n</ul>\n<p>使用这个区别，你可以确定何时需要使用异步版本，何时不需要。例如，以下是一个有效的异步查询示例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>user <span class=\"o\">=</span> <span class=\"k\">await</span> User<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>username<span class=\"o\">=</span>my_input<span class=\"p\">)</span><span class=\"o\">.</span>afirst<span class=\"p\">()</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">filter()</code> 返回一个查询集，因此在异步环境中可以继续链式调用它，而 <code class=\"docutils literal notranslate\">first()</code> 会计算并返回一个模型实例 - 因此，我们改用 <code class=\"docutils literal notranslate\">afirst()</code>，并在整个表达式的前面使用 <code class=\"docutils literal notranslate\">await</code> 以异步友好的方式调用它。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>如果你忘记了加上 <code class=\"docutils literal notranslate\">await</code>，你可能会看到类似 <em>&quot;coroutine object has no attribute x&quot;</em> 的错误，或者在你的模型实例位置看到 <em>&quot;&lt;coroutine …&gt;&quot;</em> 字符串。如果你看到这些错误，说明你忘记了在某个地方添加 <code class=\"docutils literal notranslate\">await</code> 来将协程转换为真实值。</p>\n</aside>\n</section>\n<section id=\"no-deferred-queries\">\n<h3>No deferred queries<a class=\"heading-anchor\" href=\"#no-deferred-queries\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Relations are deferred by default. If the <code class=\"docutils literal notranslate\">blog</code> relation is not prefetched,\naccessing <code class=\"docutils literal notranslate\">entry.blog</code> during asynchronous evaluation of a queryset attempts\na blocking database query, raising <code class=\"docutils literal notranslate\">SynchronousOnlyOperation</code>. (A similar\nlimitation applies to fields deferred via <code class=\"docutils literal notranslate\">defer()</code> or <code class=\"docutils literal notranslate\">only()</code>.) To avoid\nthis, see the advice on prefetching in <a class=\"reference internal\" href=\"#topics-db-queries-related\"><span class=\"std std-ref\">关联对象</span></a>.</p>\n</section>\n<section id=\"transactions\">\n<h3>事务<a class=\"heading-anchor\" href=\"#transactions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>目前，异步查询和更新 <strong>不</strong> 支持事务。如果尝试在异步查询中使用事务，会引发 <code class=\"docutils literal notranslate\">SynchronousOnlyOperation</code> 错误。</p>\n<p>如果希望使用事务，建议将 ORM 代码编写在单独的同步函数中，然后使用 <code class=\"docutils literal notranslate\">sync_to_async</code> 来调用它 - 参阅 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/async/\"><span class=\"doc\">异步支持</span></a> 获取更多信息。</p>\n</section>\n</section>\n<section id=\"querying-jsonfield\">\n<span id=\"id9\"></span><h2>查询 <code class=\"docutils literal notranslate\">JSONField</code><a class=\"heading-anchor\" href=\"#querying-jsonfield\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.JSONField\" title=\"django.db.models.JSONField\"><code class=\"xref py py-class docutils literal notranslate\">JSONField</code></a> 里的查找实现是不一样的，主要因为存在键转换。为了演示，我们将使用下面这个例子：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Dog</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    data <span class=\"o\">=</span> models<span class=\"o\">.</span>JSONField<span class=\"p\">(</span>null<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>name\n</code></pre></div>\n<section id=\"storing-and-querying-for-none\">\n<span id=\"id10\"></span><h3>保存和查询 <code class=\"docutils literal notranslate\">None</code> 值<a class=\"heading-anchor\" href=\"#storing-and-querying-for-none\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>As with other fields, storing <code class=\"docutils literal notranslate\">None</code> as the field's value will store it as\nSQL <code class=\"docutils literal notranslate\">NULL</code>. While not recommended, it is possible to store JSON scalar\n<code class=\"docutils literal notranslate\">null</code> instead of SQL <code class=\"docutils literal notranslate\">NULL</code> by using the <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/expressions/#django.db.models.JSONNull\" title=\"django.db.models.JSONNull\"><code class=\"xref py py-class docutils literal notranslate\">JSONNull()</code></a> expression.</p>\n<p>无论存储哪种值，当从数据库检索时，JSON 标量 <code class=\"docutils literal notranslate\">null</code> 的 Python 表示法与 SQL 的 <code class=\"docutils literal notranslate\">NULL</code> 相同，即 <code class=\"docutils literal notranslate\">None</code>。因此，可能很难区分它们。</p>\n<p>This only applies to <code class=\"docutils literal notranslate\">None</code> as the top-level value of the field. If <code class=\"docutils literal notranslate\">None</code>\nis inside a <a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">list</code></a> or <a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">dict</code></a>, it will always be interpreted\nas JSON <code class=\"docutils literal notranslate\">null</code>.</p>\n<p>When querying, <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-isnull\"><code class=\"xref std std-lookup docutils literal notranslate\">isnull=True</code></a> is used to match SQL <code class=\"docutils literal notranslate\">NULL</code>,\nwhile exact-matching <code class=\"docutils literal notranslate\">JSONNull()</code> is used to match JSON <code class=\"docutils literal notranslate\">null</code>.</p>\n<aside class=\"version-note version-deprecated\" data-version=\"6.1\" role=\"note\">\n<p class=\"version-note-title\">Deprecated since Django 6.1</p><p><span class=\"versionmodified deprecated\">Deprecated since version 6.1: </span>Exact-matching <code class=\"docutils literal notranslate\">None</code> in a query to mean JSON <code class=\"docutils literal notranslate\">null</code> is deprecated.\nAfter the deprecation period, it will be interpreted as SQL <code class=\"docutils literal notranslate\">NULL</code>.</p>\n</aside>\n<aside class=\"version-note version-changed\" data-version=\"6.1\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 6.1</p><p><code class=\"docutils literal notranslate\">JSONNull()</code> expression was added.</p>\n</aside>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> JSONNull\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Max&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>  <span class=\"c1\"># SQL NULL.</span>\n<span class=\"go\">&lt;Dog: Max&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Archie&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span>JSONNull<span class=\"p\">())</span>  <span class=\"c1\"># JSON null.</span>\n<span class=\"go\">&lt;Dog: Archie&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>\n<span class=\"go\">...: RemovedInDjango2028Warning: Using None as the right-hand side of an</span>\n<span class=\"go\">exact lookup on JSONField to mean JSON scalar &#39;null&#39; is deprecated. Use</span>\n<span class=\"go\">JSONNull() instead (or use the __isnull lookup if you meant SQL NULL).</span>\n<span class=\"go\">...</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Archie&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data<span class=\"o\">=</span>JSONNull<span class=\"p\">())</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Archie&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__isnull<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Max&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__isnull<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Archie&gt;]&gt;</span>\n</code></pre></div>\n<p>除非你确定要使用 SQL 的 <code class=\"docutils literal notranslate\">NULL</code> 值，否则请考虑设置 <code class=\"docutils literal notranslate\">null=False</code> 并为空值提供合适的默认值，例如 <code class=\"docutils literal notranslate\">default=dict</code> 。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>保存 JSON 的 <code class=\"docutils literal notranslate\">null</code> 值不违反 Django 的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.Field.null\" title=\"django.db.models.Field.null\"><code class=\"xref py py-attr docutils literal notranslate\">null=False</code></a> 。</p>\n</aside>\n<aside class=\"admonition-storing-json-null-inside-json-data admonition\" role=\"note\">\n<p class=\"admonition-title\">Storing JSON <code class=\"docutils literal notranslate\">null</code> inside JSON data</p>\n<p>While <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/expressions/#django.db.models.JSONNull\" title=\"django.db.models.JSONNull\"><code class=\"xref py py-class docutils literal notranslate\">JSONNull()</code></a> can be used in\n<a class=\"reference internal\" href=\"#std-fieldlookup-jsonfield.key\"><code class=\"xref std std-lookup docutils literal notranslate\">jsonfield.key</code></a> exact lookups, it cannot be stored inside\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">dict</code></a> or <a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">list</code></a> instances meant to be saved in a\n<code class=\"docutils literal notranslate\">JSONField</code>, unless a custom encoder is used. If you don't want to use\na custom encoder, use <code class=\"docutils literal notranslate\">None</code> instead.</p>\n</aside>\n</section>\n<section id=\"key-index-and-path-transforms\">\n<span id=\"std-fieldlookup-jsonfield.key\"></span><span id=\"id11\"></span><h3>键、索引和路径转换<a class=\"heading-anchor\" href=\"#key-index-and-path-transforms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>要基于给定的字典键进行查询，请将该键用作查找名称：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    name<span class=\"o\">=</span><span class=\"s2\">&quot;Rufus&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    data<span class=\"o\">=</span><span class=\"p\">{</span>\n<span class=\"gp\">... </span>        <span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;labrador&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>        <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>            <span class=\"s2\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>            <span class=\"s2\">&quot;other_pets&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n<span class=\"gp\">... </span>                <span class=\"p\">{</span>\n<span class=\"gp\">... </span>                    <span class=\"s2\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Fishy&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>                <span class=\"p\">}</span>\n<span class=\"gp\">... </span>            <span class=\"p\">],</span>\n<span class=\"gp\">... </span>        <span class=\"p\">},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">},</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Dog: Rufus&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Meg&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"kc\">None</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__breed<span class=\"o\">=</span><span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</span>\n</code></pre></div>\n<p>To query a key for JSON <code class=\"docutils literal notranslate\">null</code>, <code class=\"docutils literal notranslate\">None</code> or <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/expressions/#django.db.models.JSONNull\" title=\"django.db.models.JSONNull\"><code class=\"xref py py-class docutils literal notranslate\">JSONNull()</code></a> can be used.</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__owner<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__owner<span class=\"o\">=</span>JSONNull<span class=\"p\">())</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n</code></pre></div>\n<p>可以将多个键链接在一起以形成路径查找：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__owner__name<span class=\"o\">=</span><span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Rufus&gt;]&gt;</span>\n</code></pre></div>\n<p>如果键是整数，则将其解释为数组中的索引变换：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__owner__other_pets__0__name<span class=\"o\">=</span><span class=\"s2\">&quot;Fishy&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Rufus&gt;]&gt;</span>\n</code></pre></div>\n<p>If the key is a negative integer, it cannot be used in a filter keyword\ndirectly, but you can still use dictionary unpacking to use it in a query:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span><span class=\"o\">**</span><span class=\"p\">{</span><span class=\"s2\">&quot;data__owner__other_pets__-1__name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Fishy&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Rufus&gt;]&gt;</span>\n</code></pre></div>\n<aside class=\"admonition-mysql-mariadb-and-oracle-21c admonition\" role=\"note\">\n<p class=\"admonition-title\">MySQL, MariaDB, and Oracle &lt; 21c</p>\n<p>Negative JSON array indices are not supported.</p>\n</aside>\n<aside class=\"version-note version-changed\" data-version=\"6.0\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 6.0</p><p>SQLite support for negative JSON array indices was added.</p>\n</aside>\n<aside class=\"version-note version-changed\" data-version=\"6.1\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 6.1</p><p>Oracle 21c+ support for negative JSON array indices was added.</p>\n</aside>\n<p>如果要查询的键与另一个查询的键名冲突，请改用 <a class=\"reference internal\" href=\"#std-fieldlookup-jsonfield.contains\"><code class=\"xref std std-lookup docutils literal notranslate\">contains</code></a> 来查询。</p>\n<p>要查询缺少的键，请使用 <code class=\"docutils literal notranslate\">isnull</code> 查找：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Shep&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Shep&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__owner__isnull<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Shep&gt;]&gt;</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>上面给出的例子隐式地使用了 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-exact\"><code class=\"xref std std-lookup docutils literal notranslate\">exact</code></a> 查找。Key，索引和路径转换也可以用：<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-icontains\"><code class=\"xref std std-lookup docutils literal notranslate\">icontains</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-endswith\"><code class=\"xref std std-lookup docutils literal notranslate\">endswith</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-iendswith\"><code class=\"xref std std-lookup docutils literal notranslate\">iendswith</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-iexact\"><code class=\"xref std std-lookup docutils literal notranslate\">iexact</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-regex\"><code class=\"xref std std-lookup docutils literal notranslate\">regex</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-iregex\"><code class=\"xref std std-lookup docutils literal notranslate\">iregex</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-startswith\"><code class=\"xref std std-lookup docutils literal notranslate\">startswith</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-istartswith\"><code class=\"xref std std-lookup docutils literal notranslate\">istartswith</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-lt\"><code class=\"xref std std-lookup docutils literal notranslate\">lt</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-lte\"><code class=\"xref std std-lookup docutils literal notranslate\">lte</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-gt\"><code class=\"xref std std-lookup docutils literal notranslate\">gt</code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-gte\"><code class=\"xref std std-lookup docutils literal notranslate\">gte</code></a> 以及 <a class=\"reference internal\" href=\"#containment-and-key-lookups\"><span class=\"std std-ref\">包含与键查找</span></a> 。</p>\n</aside>\n<section id=\"module-django.db.models.fields.json\">\n<span id=\"kt-expressions\"></span><h4><code class=\"docutils literal notranslate\">KT()</code> 表达式<a class=\"heading-anchor\" href=\"#module-django.db.models.fields.json\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.fields.json.KT\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">KT</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">lookup</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.fields.json.KT\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>表示 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.JSONField\" title=\"django.db.models.JSONField\"><code class=\"xref py py-class docutils literal notranslate\">JSONField</code></a> 的键、索引或路径变换的文本值。您可以在 <code class=\"docutils literal notranslate\">lookup</code> 中使用双下划线符号来链接字典键和索引变换。</p>\n<p>例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models.fields.json</span> <span class=\"kn\">import</span> KT\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    name<span class=\"o\">=</span><span class=\"s2\">&quot;Shep&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    data<span class=\"o\">=</span><span class=\"p\">{</span>\n<span class=\"gp\">... </span>        <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">},</span>\n<span class=\"gp\">... </span>        <span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;lhasa apso&quot;</span><span class=\"p\">],</span>\n<span class=\"gp\">... </span>    <span class=\"p\">},</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Dog: Shep&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    first_breed<span class=\"o\">=</span>KT<span class=\"p\">(</span><span class=\"s2\">&quot;data__breed__1&quot;</span><span class=\"p\">),</span> owner_name<span class=\"o\">=</span>KT<span class=\"p\">(</span><span class=\"s2\">&quot;data__owner__name&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>first_breed__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;lhasa&quot;</span><span class=\"p\">,</span> owner_name<span class=\"o\">=</span><span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Shep&gt;]&gt;</span>\n</code></pre></div>\n</dd></dl>\n\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>由于键-路径查询的工作方式，<code class=\"xref py py-meth docutils literal notranslate\">exclude()</code> 和 <code class=\"xref py py-meth docutils literal notranslate\">filter()</code> 不能保证产生详尽的集合。如果你想包含没有路径的对象，请添加 <code class=\"docutils literal notranslate\">isnull</code> 查找。</p>\n</aside>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>由于任何字符串都可以成为 JSON 对象中的一个键，除了下面列出的那些之外，任何查询都将被解释为一个键查询。不会出现错误。要格外小心打字错误，并经常检查你的查询是否按你的意图进行。</p>\n</aside>\n<aside class=\"admonition-mariadb-and-oracle-users admonition\" role=\"note\">\n<p class=\"admonition-title\">MariaDB 和 Oracle 用户</p>\n<p>在键、索引或路径转换上使用 <code class=\"xref py py-meth docutils literal notranslate\">order_by()</code> 将使用值的字符串表示法对对象进行排序。这是因为 MariaDB 和 Oracle 数据库没有提供将 JSON 值转换为其等价的 SQL 值的函数。</p>\n</aside>\n<aside class=\"admonition-oracle-users admonition\" role=\"note\">\n<p class=\"admonition-title\">Oracle 用户</p>\n<p>在 Oracle 数据库中，在 <code class=\"xref py py-meth docutils literal notranslate\">exclude()</code> 查询中使用 <code class=\"docutils literal notranslate\">None</code> 作为查询值，将返回没有 <code class=\"docutils literal notranslate\">null</code> 作为指定路径的对象，包括没有路径的对象。在其他数据库后端，该查询将返回具有该路径且其值不是 <code class=\"docutils literal notranslate\">null</code> 的对象。</p>\n</aside>\n<aside class=\"admonition-postgresql-users admonition\" role=\"note\">\n<p class=\"admonition-title\">PostgreSQL 用户</p>\n<p>在 PostgreSQL 上，如果只使用一个键或索引，那么会使用 SQL 运算符 <code class=\"docutils literal notranslate\">-&gt;</code> 。如果使用多个操作符，则会使用 <code class=\"docutils literal notranslate\">#&gt;</code> 运算符。</p>\n</aside>\n<aside class=\"admonition-sqlite-users admonition\" role=\"note\">\n<p class=\"admonition-title\">SQLite 用户</p>\n<p>在SQLite上，字符串值 <code class=\"docutils literal notranslate\">&quot;true&quot;</code>、<code class=\"docutils literal notranslate\">&quot;false&quot;</code> 和 <code class=\"docutils literal notranslate\">&quot;null&quot;</code> 将始终被解释为分别为 <code class=\"docutils literal notranslate\">True</code>、<code class=\"docutils literal notranslate\">False</code> 和 JSON <code class=\"docutils literal notranslate\">null</code>。</p>\n</aside>\n</section>\n</section>\n<section id=\"containment-and-key-lookups\">\n<span id=\"id12\"></span><h3>包含与键查找<a class=\"heading-anchor\" href=\"#containment-and-key-lookups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"contains\">\n<span id=\"std-fieldlookup-jsonfield.contains\"></span><h4><code class=\"docutils literal notranslate\">contains</code><a class=\"heading-anchor\" href=\"#contains\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#std-fieldlookup-contains\"><code class=\"xref std std-lookup docutils literal notranslate\">contains</code></a> 查询在 <code class=\"docutils literal notranslate\">JSONField</code> 上被覆盖。返回的对象是那些包含给定键值对的顶层字段的对象。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Rufus&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;labrador&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Rufus&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Meg&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Fred&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{})</span>\n<span class=\"go\">&lt;Dog: Fred&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    name<span class=\"o\">=</span><span class=\"s2\">&quot;Merry&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;pekingese&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;tricks&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;fetch&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;dance&quot;</span><span class=\"p\">]}</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__contains<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Rufus&gt;, &lt;Dog: Meg&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__contains<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__contains<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;tricks&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;dance&quot;</span><span class=\"p\">]})</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Merry&gt;]&gt;</span>\n</code></pre></div>\n<aside class=\"admonition-oracle-and-sqlite admonition\" role=\"note\">\n<p class=\"admonition-title\">Oracle 和 SQLite</p>\n<p>Oracle 和 SQLite 不支持 <code class=\"docutils literal notranslate\">contains</code> 。</p>\n</aside>\n</section>\n<section id=\"contained-by\">\n<span id=\"std-fieldlookup-jsonfield.contained_by\"></span><h4><code class=\"docutils literal notranslate\">contained_by</code><a class=\"heading-anchor\" href=\"#contained-by\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>这是 <a class=\"reference internal\" href=\"#std-fieldlookup-jsonfield.contains\"><code class=\"xref std std-lookup docutils literal notranslate\">contains</code></a> 查询的反向 - 返回的对象将是那些对象，其上的键值对是传递值中的子集。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Rufus&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;labrador&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Rufus&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Meg&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Fred&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{})</span>\n<span class=\"go\">&lt;Dog: Fred&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    name<span class=\"o\">=</span><span class=\"s2\">&quot;Merry&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;pekingese&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;tricks&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;fetch&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;dance&quot;</span><span class=\"p\">]}</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__contained_by<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Meg&gt;, &lt;Dog: Fred&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__contained_by<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Fred&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    data__contained_by<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;pekingese&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;tricks&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;dance&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;fetch&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;hug&quot;</span><span class=\"p\">]}</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Merry&gt;, &lt;Dog: Fred&gt;]&gt;</span>\n</code></pre></div>\n<aside class=\"admonition-oracle-and-sqlite admonition\" role=\"note\">\n<p class=\"admonition-title\">Oracle 和 SQLite</p>\n<p>Oracle 和 SQLite 不支持 <code class=\"docutils literal notranslate\">contained_by</code> 。</p>\n</aside>\n</section>\n<section id=\"has-key\">\n<span id=\"std-fieldlookup-jsonfield.has_key\"></span><h4><code class=\"docutils literal notranslate\">has_key</code><a class=\"heading-anchor\" href=\"#has-key\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>返回具有给定键位于数据的顶层的对象。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Rufus&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;labrador&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Rufus&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Meg&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__has_key<span class=\"o\">=</span><span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"has-keys\">\n<span id=\"std-fieldlookup-jsonfield.has_keys\"></span><h4><code class=\"docutils literal notranslate\">has_keys</code><a class=\"heading-anchor\" href=\"#has-keys\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>返回所有给定键位于数据的顶层的对象。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Rufus&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;labrador&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Rufus&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Meg&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;collie&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__has_keys<span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">])</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"has-any-keys\">\n<span id=\"std-fieldlookup-jsonfield.has_any_keys\"></span><h4><code class=\"docutils literal notranslate\">has_any_keys</code><a class=\"heading-anchor\" href=\"#has-any-keys\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>返回任何给定键位于数据的顶层的对象。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Rufus&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;labrador&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Rufus&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Meg&quot;</span><span class=\"p\">,</span> data<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Bob&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&lt;Dog: Meg&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Dog<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>data__has_any_keys<span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;owner&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;breed&quot;</span><span class=\"p\">])</span>\n<span class=\"go\">&lt;QuerySet [&lt;Dog: Rufus&gt;, &lt;Dog: Meg&gt;]&gt;</span>\n</code></pre></div>\n</section>\n</section>\n</section>\n<section id=\"complex-lookups-with-q-objects\">\n<span id=\"complex-lookups-with-q\"></span><h2>通过 <code class=\"docutils literal notranslate\">Q</code> 对象完成复杂查询<a class=\"heading-anchor\" href=\"#complex-lookups-with-q-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Keyword argument queries -- in <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a>,\netc. -- are &quot;AND&quot;ed together. If you need to execute more complex queries (for\nexample, queries with <code class=\"docutils literal notranslate\">OR</code> statements), you can use <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#q-objects\"><span class=\"std std-ref\">Q() 对象</span></a>.</p>\n<p>A <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#q-objects\"><span class=\"std std-ref\">Q object</span></a> (<code class=\"docutils literal notranslate\">django.db.models.Q</code>) is an object used to\nencapsulate a collection of keyword arguments. These keyword arguments are\nspecified as in &quot;Field lookups&quot; above.</p>\n<p>例如，该 <code class=\"docutils literal notranslate\">Q</code> 对象压缩了一个 <code class=\"docutils literal notranslate\">LIKE</code> 查询:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Q\n\nQ<span class=\"p\">(</span>question__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;What&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">Q</code> 对象可以使用 <code class=\"docutils literal notranslate\">&amp;</code>、<code class=\"docutils literal notranslate\">|</code> 和 <code class=\"docutils literal notranslate\">^</code> 运算符组合。当在两个 <code class=\"docutils literal notranslate\">Q</code> 对象上使用运算符时，它会产生一个新的 <code class=\"docutils literal notranslate\">Q</code> 对象。</p>\n<p>例如，该语句生成一个 <code class=\"docutils literal notranslate\">Q</code> 对象，表示两个 <code class=\"docutils literal notranslate\">&quot;question_startswith&quot;</code> 查询语句之间的 &quot;OR&quot; 关系:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Q<span class=\"p\">(</span>question__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;Who&quot;</span><span class=\"p\">)</span> <span class=\"o\">|</span> Q<span class=\"p\">(</span>question__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;What&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>这等同于以下 SQL 的 WHERE 子句：</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">WHERE</span> question <span class=\"k\">LIKE</span> <span class=\"s1\">&#39;Who%&#39;</span> <span class=\"k\">OR</span> question <span class=\"k\">LIKE</span> <span class=\"s1\">&#39;What%&#39;</span>\n</code></pre></div>\n<p>您可以使用 <code class=\"docutils literal notranslate\">&amp;</code>、<code class=\"docutils literal notranslate\">|</code> 和 <code class=\"docutils literal notranslate\">^</code> 运算符组合任意复杂的语句，并使用括号进行分组。此外，可以使用 <code class=\"docutils literal notranslate\">~</code> 运算符对 <code class=\"docutils literal notranslate\">Q</code> 对象进行取反，从而允许组合查询，既包括正常查询又包括取反（<code class=\"docutils literal notranslate\">NOT</code>）查询：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Q<span class=\"p\">(</span>question__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;Who&quot;</span><span class=\"p\">)</span> <span class=\"o\">|</span> <span class=\"o\">~</span>Q<span class=\"p\">(</span>pub_date__year<span class=\"o\">=</span><span class=\"mi\">2005</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>每个接受关键字参数的查询函数 (例如 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a>， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\">exclude()</code></a>， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a>) 也同时接受一个或多个 <code class=\"docutils literal notranslate\">Q</code> 对象作为位置（未命名的）参数。若你为查询函数提供了多个 <code class=\"docutils literal notranslate\">Q</code> 对象参数，这些参数会通过 &quot;AND&quot; 连接。例子:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Poll<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>\n    Q<span class=\"p\">(</span>question__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;Who&quot;</span><span class=\"p\">),</span>\n    Q<span class=\"p\">(</span>pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span> <span class=\"o\">|</span> Q<span class=\"p\">(</span>pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">)),</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>...粗略地转为 SQL：</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span> <span class=\"o\">*</span> <span class=\"k\">from</span> polls <span class=\"k\">WHERE</span> question <span class=\"k\">LIKE</span> <span class=\"s1\">&#39;Who%&#39;</span>\n    <span class=\"k\">AND</span> <span class=\"p\">(</span>pub_date <span class=\"o\">=</span> <span class=\"s1\">&#39;2005-05-02&#39;</span> <span class=\"k\">OR</span> pub_date <span class=\"o\">=</span> <span class=\"s1\">&#39;2005-05-06&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>查询函数能混合使用 <code class=\"docutils literal notranslate\">Q</code> 对象和关键字参数。所有提供给查询函数的参数（即关键字参数或 <code class=\"docutils literal notranslate\">Q</code> 对象）均通过 &quot;AND&quot; 连接。然而，若提供了 <code class=\"docutils literal notranslate\">Q</code> 对象，那么它必须位于所有关键字参数之前。例子:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Poll<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>\n    Q<span class=\"p\">(</span>pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span> <span class=\"o\">|</span> Q<span class=\"p\">(</span>pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">)),</span>\n    question__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;Who&quot;</span><span class=\"p\">,</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>……会是一个有效的查询，等效于前文的例子；但是:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># INVALID QUERY</span>\nPoll<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>\n    question__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;Who&quot;</span><span class=\"p\">,</span>\n    Q<span class=\"p\">(</span>pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span> <span class=\"o\">|</span> Q<span class=\"p\">(</span>pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">)),</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>……却是无效的。</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">See also</p>\n<p>Django 单元测试中的 <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/6.1.x/tests/or_lookups/tests.py\">OR 查询实例</a> 展示了 <code class=\"docutils literal notranslate\">Q</code> 的用法。</p>\n</aside>\n</section>\n<section id=\"comparing-objects\">\n<h2>比较对象<a class=\"heading-anchor\" href=\"#comparing-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>要比较两个模型实例，使用标准的 Python 比较操作符，两个等号： <code class=\"docutils literal notranslate\">==</code>。实际上，这比较了两个模型实例的主键值。</p>\n<p>使用上面的 <code class=\"docutils literal notranslate\">Entry</code> 示例，下面的两个语句是等效的：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>some_entry <span class=\"o\">==</span> other_entry\n<span class=\"gp\">&gt;&gt;&gt; </span>some_entry<span class=\"o\">.</span>id <span class=\"o\">==</span> other_entry<span class=\"o\">.</span>id\n</code></pre></div>\n<p>如果模型的主键不叫 <code class=\"docutils literal notranslate\">id</code>，也没有问题。比较操作将始终使用主键，无论它叫什么。例如，如果一个模型的主键字段叫 <code class=\"docutils literal notranslate\">name</code>，下面两个语句是等效的：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>some_obj <span class=\"o\">==</span> other_obj\n<span class=\"gp\">&gt;&gt;&gt; </span>some_obj<span class=\"o\">.</span>name <span class=\"o\">==</span> other_obj<span class=\"o\">.</span>name\n</code></pre></div>\n</section>\n<section id=\"deleting-objects\">\n<span id=\"topics-db-queries-delete\"></span><h2>删除对象<a class=\"heading-anchor\" href=\"#deleting-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>删除方法方便地被命名为 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.delete\" title=\"django.db.models.Model.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a>。这个方法立即删除对象并返回被删除的对象数以及一个包含每种对象类型的删除数的字典。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>e<span class=\"o\">.</span>delete<span class=\"p\">()</span>\n<span class=\"go\">(1, {&#39;blog.Entry&#39;: 1})</span>\n</code></pre></div>\n<p>你也能批量删除对象。所有 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 都有个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.delete\" title=\"django.db.models.query.QuerySet.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a> 方法，它会删除 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 中的所有成员。</p>\n<p>例如，这将删除所有具有 <code class=\"docutils literal notranslate\">pub_date</code> 年份为 2005 的 <code class=\"docutils literal notranslate\">Entry</code> 对象：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__year<span class=\"o\">=</span><span class=\"mi\">2005</span><span class=\"p\">)</span><span class=\"o\">.</span>delete<span class=\"p\">()</span>\n<span class=\"go\">(5, {&#39;webapp.Entry&#39;: 5})</span>\n</code></pre></div>\n<p>请记住，只要有机会的话，这会通过纯 SQL 语句执行，所以就无需在过程中调用每个对象的删除方法了。若你为模型类提供了自定义的 <code class=\"docutils literal notranslate\">delete()</code> 方法，且希望确保调用了该方法，你需要 “手动” 删除该模型的实例（例如，如，遍历 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>，在每个对象上分别调用 <code class=\"docutils literal notranslate\">delete()</code> 方法），而不是使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 的批量删除方法 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.delete\" title=\"django.db.models.query.QuerySet.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a>。</p>\n<p>当 Django 删除某个对象时，默认会模仿 SQL 约束 <code class=\"docutils literal notranslate\">ON DELETE CASCADE</code> 的行为——换而言之，某个对象被删除时，关联对象也会被删除。例子:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>b <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"c1\"># This will delete the Blog and all of its Entry objects.</span>\nb<span class=\"o\">.</span>delete<span class=\"p\">()</span>\n</code></pre></div>\n<p>这种约束行为由 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey.on_delete\" title=\"django.db.models.ForeignKey.on_delete\"><code class=\"xref py py-attr docutils literal notranslate\">on_delete</code></a> 参数指定。</p>\n<p>注意 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.delete\" title=\"django.db.models.query.QuerySet.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a> 是唯一未在 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> 上暴漏的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 方法。这是一种安全机制，避免你不小心调用了 <code class=\"docutils literal notranslate\">Entry.objects.delete()</code>，删除了 <em>所有的</em> 条目。若你 <em>确实</em> 想要删除所有对象，你必须显示请求完整结果集合:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span><span class=\"o\">.</span>delete<span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"copying-model-instances\">\n<span id=\"topics-db-queries-copy\"></span><h2>复制模型实例<a class=\"heading-anchor\" href=\"#copying-model-instances\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>虽然没有内置的方法来复制模型实例，但可以轻松地创建新的实例，并复制所有字段的值。在最简单的情况下，您可以将 <code class=\"docutils literal notranslate\">pk</code> 设置为 <code class=\"docutils literal notranslate\">None</code> 并将 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model._state\" title=\"django.db.models.Model._state\"><code class=\"xref py py-attr docutils literal notranslate\">_state.adding</code></a> 设置为 <code class=\"docutils literal notranslate\">True</code>。使用我们的博客示例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>blog <span class=\"o\">=</span> Blog<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;My blog&quot;</span><span class=\"p\">,</span> tagline<span class=\"o\">=</span><span class=\"s2\">&quot;Blogging is easy&quot;</span><span class=\"p\">)</span>\nblog<span class=\"o\">.</span>save<span class=\"p\">()</span>  <span class=\"c1\"># blog.pk == 1</span>\n\nblog<span class=\"o\">.</span>pk <span class=\"o\">=</span> <span class=\"kc\">None</span>\nblog<span class=\"o\">.</span>_state<span class=\"o\">.</span>adding <span class=\"o\">=</span> <span class=\"kc\">True</span>\nblog<span class=\"o\">.</span>save<span class=\"p\">()</span>  <span class=\"c1\"># blog.pk == 2</span>\n</code></pre></div>\n<p>若你使用了集成，事情会更复杂。考虑下 <code class=\"docutils literal notranslate\">Blog</code> 的一个子类:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">ThemeBlog</span><span class=\"p\">(</span>Blog<span class=\"p\">):</span>\n    theme <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n\n\ndjango_blog <span class=\"o\">=</span> ThemeBlog<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Django&quot;</span><span class=\"p\">,</span> tagline<span class=\"o\">=</span><span class=\"s2\">&quot;Django is easy&quot;</span><span class=\"p\">,</span> theme<span class=\"o\">=</span><span class=\"s2\">&quot;python&quot;</span><span class=\"p\">)</span>\ndjango_blog<span class=\"o\">.</span>save<span class=\"p\">()</span>  <span class=\"c1\"># django_blog.pk == 3</span>\n</code></pre></div>\n<p>由于继承的工作方式，您必须将 <code class=\"docutils literal notranslate\">pk</code> 和 <code class=\"docutils literal notranslate\">id</code> 都设置为 <code class=\"docutils literal notranslate\">None</code>，并将 <code class=\"docutils literal notranslate\">_state.adding</code> 设置为 <code class=\"docutils literal notranslate\">True</code>：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>django_blog<span class=\"o\">.</span>pk <span class=\"o\">=</span> <span class=\"kc\">None</span>\ndjango_blog<span class=\"o\">.</span>id <span class=\"o\">=</span> <span class=\"kc\">None</span>\ndjango_blog<span class=\"o\">.</span>_state<span class=\"o\">.</span>adding <span class=\"o\">=</span> <span class=\"kc\">True</span>\ndjango_blog<span class=\"o\">.</span>save<span class=\"p\">()</span>  <span class=\"c1\"># django_blog.pk == 4</span>\n</code></pre></div>\n<p>该方法不会拷贝不是模型数据表中的关联关系。例如， <code class=\"docutils literal notranslate\">Entry</code> 有一个对 <code class=\"docutils literal notranslate\">Author</code> 的 <code class=\"docutils literal notranslate\">ManyToManyField</code> 关联关系。在复制条目后，你必须为新条目设置多对多关联关系。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>entry <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>  <span class=\"c1\"># some previous entry</span>\nold_authors <span class=\"o\">=</span> entry<span class=\"o\">.</span>authors<span class=\"o\">.</span>all<span class=\"p\">()</span>\nentry<span class=\"o\">.</span>pk <span class=\"o\">=</span> <span class=\"kc\">None</span>\nentry<span class=\"o\">.</span>_state<span class=\"o\">.</span>adding <span class=\"o\">=</span> <span class=\"kc\">True</span>\nentry<span class=\"o\">.</span>save<span class=\"p\">()</span>\nentry<span class=\"o\">.</span>authors<span class=\"o\">.</span>set<span class=\"p\">(</span>old_authors<span class=\"p\">)</span>\n</code></pre></div>\n<p>对于 <code class=\"docutils literal notranslate\">OneToOneField</code> 关联，你必须拷贝关联对象，并将其指定给新对象的关联字段，避免违反一对一唯一性约束。例如，指定前文复制的 <code class=\"docutils literal notranslate\">entry</code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>detail <span class=\"o\">=</span> EntryDetail<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\ndetail<span class=\"o\">.</span>pk <span class=\"o\">=</span> <span class=\"kc\">None</span>\ndetail<span class=\"o\">.</span>_state<span class=\"o\">.</span>adding <span class=\"o\">=</span> <span class=\"kc\">True</span>\ndetail<span class=\"o\">.</span>entry <span class=\"o\">=</span> entry\ndetail<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>Note that it is not possible to copy instances of models with deferred fields\nusing this pattern unless values are assigned to them:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>blog <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>defer<span class=\"p\">(</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>blog<span class=\"o\">.</span>pk <span class=\"o\">=</span> <span class=\"kc\">None</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>blog<span class=\"o\">.</span>_state<span class=\"o\">.</span>adding <span class=\"o\">=</span> <span class=\"kc\">True</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>blog<span class=\"o\">.</span>save<span class=\"p\">()</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n    <span class=\"o\">...</span>\n<span class=\"gr\">AttributeError</span>: Cannot retrieve deferred field &#39;name&#39; from an unsaved model.\n<span class=\"gp\">&gt;&gt;&gt; </span>blog<span class=\"o\">.</span>name <span class=\"o\">=</span> <span class=\"s2\">&quot;Another Blog&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>blog<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"updating-multiple-objects-at-once\">\n<span id=\"topics-db-queries-update\"></span><h2>一次修改多个对象<a class=\"heading-anchor\" href=\"#updating-multiple-objects-at-once\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>有时候，你想统一设置 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 中的所有对象的某个字段。你可以通过 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.update\" title=\"django.db.models.query.QuerySet.update\"><code class=\"xref py py-meth docutils literal notranslate\">update()</code></a> 达到目的。例子:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># Update all the headlines with pub_date in 2007.</span>\nEntry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pub_date__year<span class=\"o\">=</span><span class=\"mi\">2007</span><span class=\"p\">)</span><span class=\"o\">.</span>update<span class=\"p\">(</span>headline<span class=\"o\">=</span><span class=\"s2\">&quot;Everything is the same&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>您只能使用此方法设置非关联字段和 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 字段。要更新非关联字段，请将新值提供为常数。要更新 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 字段，请将新值设置为要指向的新模型实例。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>b <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n<span class=\"go\"># Change every Entry so that it belongs to this Blog.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>update<span class=\"p\">(</span>blog<span class=\"o\">=</span>b<span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">update()</code> 方法会立即应用，并返回查询匹配的行数（如果某些行已经具有新值，则可能不等于更新的行数）。对于要更新的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 唯一的限制是它只能访问一个数据库表：模型的主表。您可以基于相关字段进行过滤，但只能更新模型的主表中的列。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>b <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n<span class=\"go\"># Update all the headlines belonging to this Blog.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog<span class=\"o\">=</span>b<span class=\"p\">)</span><span class=\"o\">.</span>update<span class=\"p\">(</span>headline<span class=\"o\">=</span><span class=\"s2\">&quot;Everything is the same&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>要认识到 <code class=\"docutils literal notranslate\">update()</code> 方法是直接转为 SQL 语句的。这是一种用于直接更新的批量操作。它并不会调用模型的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 方法，或发射 <code class=\"docutils literal notranslate\">pre_save</code> 或 <code class=\"docutils literal notranslate\">post_save</code> 信号（调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 会触发信号），或使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.DateField.auto_now\" title=\"django.db.models.DateField.auto_now\"><code class=\"xref py py-attr docutils literal notranslate\">auto_now</code></a> 字段选项。若想保存 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 中的每项，并确保调用了每个实例的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 方法，你并不需要任何特殊的函数来处理此问题。迭代它们，并调用它们的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 方法:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">for</span> item <span class=\"ow\">in</span> my_queryset<span class=\"p\">:</span>\n    item<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>Calls to update can also use <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/expressions/#f-expressions\"><span class=\"std std-ref\">F() 表达式</span></a> to update one field based on\nthe value of another field in the model. This is especially useful for\nincrementing counters based upon their current value. For example, to increment\nthe pingback count for every entry in the blog:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>update<span class=\"p\">(</span>number_of_pingbacks<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;number_of_pingbacks&quot;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>然而，与筛选和排除子句中的 <code class=\"docutils literal notranslate\">F()</code> 对象不同，在更新中使用 <code class=\"docutils literal notranslate\">F()</code> 对象时，不能引入连接，只能引用模型被更新的字段。如果尝试使用 <code class=\"docutils literal notranslate\">F()</code> 对象引入连接，将引发 <code class=\"docutils literal notranslate\">FieldError</code> 错误：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"go\"># This will raise a FieldError</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>update<span class=\"p\">(</span>headline<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;blog__name&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n</section>\n<section id=\"related-objects\">\n<span id=\"topics-db-queries-related\"></span><h2>关联对象<a class=\"heading-anchor\" href=\"#related-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>When you define a relationship in a model (with\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a>,\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a>, or\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a>), instances of the model class gain\naccessor attributes for the related object(s).</p>\n<p>Using the models at the top of this page, for example, an <code class=\"docutils literal notranslate\">Entry</code> object\n<code class=\"docutils literal notranslate\">e</code> has its associated <code class=\"docutils literal notranslate\">Blog</code> object accessible in its <code class=\"docutils literal notranslate\">blog</code> attribute:\n<code class=\"docutils literal notranslate\">e.blog</code>.</p>\n<p>（在幕后，这个函数是由  Python <a class=\"reference external\" href=\"https://docs.python.org/3/howto/descriptor.html\" title=\"(in Python v3.14)\"><span class=\"xref std std-doc\">descriptors</span></a> 实现的。这玩意一般不会麻烦你，但是我们为你指出了注意点。）</p>\n<p>Django also creates API accessors for the &quot;other&quot; side of the relationship --\nthe link from the related model to the model that defines the relationship.\nFor example, a <code class=\"docutils literal notranslate\">Blog</code> object <code class=\"docutils literal notranslate\">b</code> has a manager that returns all related\n<code class=\"docutils literal notranslate\">Entry</code> objects in the <code class=\"docutils literal notranslate\">entry_set</code> attribute: <code class=\"docutils literal notranslate\">b.entry_set.all()</code>.</p>\n<p>These accessors may be prefetched by the <code class=\"docutils literal notranslate\">QuerySet</code> methods\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.select_related\" title=\"django.db.models.query.QuerySet.select_related\"><code class=\"xref py py-meth docutils literal notranslate\">select_related()</code></a> or\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related\" title=\"django.db.models.query.QuerySet.prefetch_related\"><code class=\"xref py py-meth docutils literal notranslate\">prefetch_related()</code></a>. If not prefetched,\naccess will trigger an on-demand fetch through the model's\n<a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/fetch-modes/\"><span class=\"doc\">fetch mode</span></a>.</p>\n<p>本章节中的所有例子都是用了本页开头定义的 <code class=\"docutils literal notranslate\">Blog</code>， <code class=\"docutils literal notranslate\">Author</code> 和 <code class=\"docutils literal notranslate\">Entry</code> 模型。</p>\n<section id=\"one-to-many-relationships\">\n<h3>一对多关联<a class=\"heading-anchor\" href=\"#one-to-many-relationships\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"forward\">\n<h4>正向访问<a class=\"heading-anchor\" href=\"#forward\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>若模型有个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a>，该模型的实例能通过其属性访问关联（外部的）对象。</p>\n<p>例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>e<span class=\"o\">.</span>blog  <span class=\"c1\"># Returns the related Blog object.</span>\n</code></pre></div>\n<p>你可以通过外键属性进行获取和设置。正如你可能期望的那样，对外键的更改直到调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> 方法后才会保存到数据库。示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>e<span class=\"o\">.</span>blog <span class=\"o\">=</span> some_blog\n<span class=\"gp\">&gt;&gt;&gt; </span>e<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>如果一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 字段设置了 <code class=\"docutils literal notranslate\">null=True</code> （即允许 <code class=\"docutils literal notranslate\">NULL</code> 值），你可以将 <code class=\"docutils literal notranslate\">None</code> 赋值给它以删除关联。示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>e<span class=\"o\">.</span>blog <span class=\"o\">=</span> <span class=\"kc\">None</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>e<span class=\"o\">.</span>save<span class=\"p\">()</span>  <span class=\"c1\"># &quot;UPDATE blog_entry SET blog_id = NULL ...;&quot;</span>\n</code></pre></div>\n<p>第一次访问与一对多关系的前向访问时，相关对象会被缓存。对同一对象实例上的外键的后续访问也会被缓存。示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>e<span class=\"o\">.</span>blog<span class=\"p\">)</span>  <span class=\"c1\"># Hits the database to retrieve the associated Blog.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>e<span class=\"o\">.</span>blog<span class=\"p\">)</span>  <span class=\"c1\"># Doesn&#39;t hit the database; uses cached version.</span>\n</code></pre></div>\n<p>请注意，<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.select_related\" title=\"django.db.models.query.QuerySet.select_related\"><code class=\"xref py py-meth docutils literal notranslate\">select_related()</code></a> <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 方法会提前递归地预加载所有一对多关系的缓存。示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>select_related<span class=\"p\">()</span><span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>e<span class=\"o\">.</span>blog<span class=\"p\">)</span>  <span class=\"c1\"># Doesn&#39;t hit the database; uses cached version.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span>e<span class=\"o\">.</span>blog<span class=\"p\">)</span>  <span class=\"c1\"># Doesn&#39;t hit the database; uses cached version.</span>\n</code></pre></div>\n</section>\n<section id=\"following-relationships-backward\">\n<span id=\"backwards-related-objects\"></span><h4>“反向” 关联<a class=\"heading-anchor\" href=\"#following-relationships-backward\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>If a model has a <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a>, instances of the\nforeign-key model will have access to a <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> that\nreturns all instances of the first model. By default, this\n<a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> is named <code class=\"docutils literal notranslate\">FOO_set</code>, where <code class=\"docutils literal notranslate\">FOO</code> is the\nsource model name, lowercased. This <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> returns\n<code class=\"docutils literal notranslate\">QuerySet</code> instances, which can be filtered and manipulated as described in\nthe &quot;Retrieving objects&quot; section above.</p>\n<p>例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>b <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>all<span class=\"p\">()</span>  <span class=\"c1\"># Returns all Entry objects related to Blog.</span>\n\n<span class=\"go\"># b.entry_set is a Manager that returns QuerySets.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>filter<span class=\"p\">(</span>headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>count<span class=\"p\">()</span>\n</code></pre></div>\n<p>你可以通过在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 定义中设置 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a> 参数来覆盖 <code class=\"docutils literal notranslate\">FOO_set</code> 的名称。例如，如果将 <code class=\"docutils literal notranslate\">Entry</code> 模型更改为 <code class=\"docutils literal notranslate\">blog = ForeignKey(Blog, on_delete=models.CASCADE, related_name='entries')</code>，那么上面的示例代码将如下所示：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>b <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>entries<span class=\"o\">.</span>all<span class=\"p\">()</span>  <span class=\"c1\"># Returns all Entry objects related to Blog.</span>\n\n<span class=\"go\"># b.entries is a Manager that returns ``QuerySet`` instances.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>entries<span class=\"o\">.</span>filter<span class=\"p\">(</span>headline__contains<span class=\"o\">=</span><span class=\"s2\">&quot;Lennon&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>b<span class=\"o\">.</span>entries<span class=\"o\">.</span>count<span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"using-a-custom-reverse-manager\">\n<span id=\"using-custom-reverse-manager\"></span><h4>使用自定义反向管理器<a class=\"heading-anchor\" href=\"#using-a-custom-reverse-manager\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/relations/#django.db.models.fields.related.RelatedManager\" title=\"django.db.models.fields.related.RelatedManager\"><code class=\"xref py py-class docutils literal notranslate\">RelatedManager</code></a> 反向关联的默认实现是该模型 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#manager-names\"><span class=\"std std-ref\">默认管理器</span></a> 一个实例。若你想为某个查询指定一个不同的管理器，可以使用如下语法:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Entry</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    objects <span class=\"o\">=</span> models<span class=\"o\">.</span>Manager<span class=\"p\">()</span>  <span class=\"c1\"># Default Manager</span>\n    entries <span class=\"o\">=</span> EntryManager<span class=\"p\">()</span>  <span class=\"c1\"># Custom Manager</span>\n\n\nb <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\nb<span class=\"o\">.</span>entry_set<span class=\"p\">(</span>manager<span class=\"o\">=</span><span class=\"s2\">&quot;entries&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>all<span class=\"p\">()</span>\n</code></pre></div>\n<p>若 <code class=\"docutils literal notranslate\">EntryManager</code> 在其 <code class=\"docutils literal notranslate\">get_queryset()</code> 方法执行了默认过滤行为，改行为会应用到 <code class=\"docutils literal notranslate\">all()</code> 调用中。</p>\n<p>指定一个自定义反向管理也允许你调用模型自定义方法:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>b<span class=\"o\">.</span>entry_set<span class=\"p\">(</span>manager<span class=\"o\">=</span><span class=\"s2\">&quot;entries&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>is_published<span class=\"p\">()</span>\n</code></pre></div>\n<aside class=\"admonition-interaction-with-prefetching admonition\" role=\"note\">\n<p class=\"admonition-title\">与预获取的互动</p>\n<p>在使用反向关系调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related\" title=\"django.db.models.query.QuerySet.prefetch_related\"><code class=\"xref py py-meth docutils literal notranslate\">prefetch_related()</code></a> 时，将使用默认管理器。如果要使用自定义反向管理器预获取相关对象，请使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.Prefetch\" title=\"django.db.models.Prefetch\"><code class=\"xref py py-class docutils literal notranslate\">Prefetch()</code></a>。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Prefetch\n\nprefetch_manager <span class=\"o\">=</span> Prefetch<span class=\"p\">(</span><span class=\"s2\">&quot;entry_set&quot;</span><span class=\"p\">,</span> queryset<span class=\"o\">=</span>Entry<span class=\"o\">.</span>entries<span class=\"o\">.</span>all<span class=\"p\">())</span>\nBlog<span class=\"o\">.</span>objects<span class=\"o\">.</span>prefetch_related<span class=\"p\">(</span>prefetch_manager<span class=\"p\">)</span>\n</code></pre></div>\n</aside>\n</section>\n<section id=\"additional-methods-to-handle-related-objects\">\n<h4>管理关联对象的额外方法<a class=\"heading-anchor\" href=\"#additional-methods-to-handle-related-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> 还有方法能处理关联对象集合。除了上面的 “检索对象” 中定义的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a> 方法以外，以下是每项的简要介绍，而完整的细节能在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/relations/\"><span class=\"doc\">关联对象参考</span></a> 中找到。</p>\n<dl class=\"simple\">\n<dt><code class=\"docutils literal notranslate\">add(obj1, obj2, ...)</code></dt><dd><p>将特定的模型对象加入关联对象集合。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\">create(**kwargs)</code></dt><dd><p>创建一个新对象，保存，并将其放入关联对象集合中。返回新创建的对象。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\">remove(obj1, obj2, ...)</code></dt><dd><p>从关联对象集合删除指定模型对象。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\">clear()</code></dt><dd><p>从关联对象集合删除所有对象。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\">set(objs)</code></dt><dd><p>替换关联对象集合</p>\n</dd>\n</dl>\n<p>要指定关联集合的成员，调用 <code class=\"docutils literal notranslate\">set()</code> 方法，并传入可迭代的对象实例集合。例如，若 <code class=\"docutils literal notranslate\">e1</code> 和 <code class=\"docutils literal notranslate\">e2</code> 都是 <code class=\"docutils literal notranslate\">Entry</code> 实例:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>b <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\nb<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>set<span class=\"p\">([</span>e1<span class=\"p\">,</span> e2<span class=\"p\">])</span>\n</code></pre></div>\n<p>如果存在 <code class=\"docutils literal notranslate\">clear()</code> 方法，则在将可迭代对象（在这种情况下是列表）中的所有对象添加到集合之前，将从 <code class=\"docutils literal notranslate\">entry_set</code> 中删除任何现有对象。如果 <em>没有</em> 可用的 <code class=\"docutils literal notranslate\">clear()</code> 方法，则将添加可迭代对象中的所有对象，而不会删除任何现有元素。</p>\n<p>本节介绍的所有 “反向” 操作对数据库都是立刻生效的。每次的增加，创建和删除都是及时自动地保存至数据库。</p>\n</section>\n</section>\n<section id=\"many-to-many-relationships\">\n<span id=\"m2m-reverse-relationships\"></span><h3>多对多关联<a class=\"heading-anchor\" href=\"#many-to-many-relationships\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>多对多关联的两端均自动获取访问另一端的 API。该 API 的工作方式类似上面的 “反向” 一对多关联。</p>\n<p>不同点在为属性命名上：定义了 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> 的模型使用字段名作为属性名，而 “反向” 模型使用源模型名的小写形式，加上 <code class=\"docutils literal notranslate\">'_set'</code> （就像反向一对多关联一样）。</p>\n<p>一个更易理解的例子:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">)</span>\ne<span class=\"o\">.</span>authors<span class=\"o\">.</span>all<span class=\"p\">()</span>  <span class=\"c1\"># Returns all Author objects for this Entry.</span>\ne<span class=\"o\">.</span>authors<span class=\"o\">.</span>count<span class=\"p\">()</span>\ne<span class=\"o\">.</span>authors<span class=\"o\">.</span>filter<span class=\"p\">(</span>name__contains<span class=\"o\">=</span><span class=\"s2\">&quot;John&quot;</span><span class=\"p\">)</span>\n\na <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span>\na<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>all<span class=\"p\">()</span>  <span class=\"c1\"># Returns all Entry objects for this Author.</span>\n</code></pre></div>\n<p>和 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 一样， <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> 能指定 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField.related_name\" title=\"django.db.models.ManyToManyField.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a>。在上面的例子中，若 <code class=\"docutils literal notranslate\">Entry</code> 中的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> 已指定了 <code class=\"docutils literal notranslate\">related_name='entries'</code>，随后每个 <code class=\"docutils literal notranslate\">Author</code> 实例会拥有一个 <code class=\"docutils literal notranslate\">entries</code> 属性，而不是 <code class=\"docutils literal notranslate\">entry_set</code>。</p>\n<p>另一个与一对多关联不同的地方是，除了模型实例以外，多对多关联中的 <code class=\"docutils literal notranslate\">add()</code>， <code class=\"docutils literal notranslate\">set()</code> 和 <code class=\"docutils literal notranslate\">remove()</code> 方法能接收主键值。例如，若 <code class=\"docutils literal notranslate\">e</code> 和 <code class=\"docutils literal notranslate\">e2</code> 是 <code class=\"docutils literal notranslate\">Entry</code> 的实例，以下两种 <code class=\"docutils literal notranslate\">set()</code> 调用结果一致:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>a <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span>\na<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>set<span class=\"p\">([</span>e1<span class=\"p\">,</span> e2<span class=\"p\">])</span>\na<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>set<span class=\"p\">([</span>e1<span class=\"o\">.</span>pk<span class=\"p\">,</span> e2<span class=\"o\">.</span>pk<span class=\"p\">])</span>\n</code></pre></div>\n<section id=\"filtering-on-many-to-many-relationships\">\n<h4>Filtering on many-to-many relationships<a class=\"heading-anchor\" href=\"#filtering-on-many-to-many-relationships\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>When calling <code class=\"docutils literal notranslate\">filter()</code> on a many-to-many relationship, be aware that the\njoin between <code class=\"docutils literal notranslate\">Entry</code> and the intermediary model to <code class=\"docutils literal notranslate\">Author</code> is performed\nonly once, resulting in a restrictive, or &quot;sticky&quot;, filter. Consider the\nfollowing example:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">datetime</span> <span class=\"kn\">import</span> date\n<span class=\"gp\">&gt;&gt;&gt; </span>batucada <span class=\"o\">=</span> Blog<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Batucada Blog&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    blog<span class=\"o\">=</span>batucada<span class=\"p\">,</span>\n<span class=\"gp\">... </span>    headline<span class=\"o\">=</span><span class=\"s2\">&quot;Supporting social movements with drums&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    pub_date<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">2019</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">14</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span>gloria <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Gloria&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>anna <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Anna&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>e<span class=\"o\">.</span>authors<span class=\"o\">.</span>add<span class=\"p\">(</span>gloria<span class=\"p\">,</span> anna<span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span>anna<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>filter<span class=\"p\">(</span>authors__name<span class=\"o\">=</span><span class=\"s2\">&quot;Gloria&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet []&gt;</span>\n</code></pre></div>\n<p>This filtered query is looking for blog entries that are co-authored by\n<code class=\"docutils literal notranslate\">anna</code> and <code class=\"docutils literal notranslate\">gloria</code>. You would expect it to return the entry <code class=\"docutils literal notranslate\">e</code>.\nHowever, the filter condition, which traverses the many-to-many\nrelationship between <code class=\"docutils literal notranslate\">Entry</code> and <code class=\"docutils literal notranslate\">Author</code>, yields an empty\n<code class=\"docutils literal notranslate\">QuerySet</code>.</p>\n<p>Since the join between <code class=\"docutils literal notranslate\">Entry</code> and the intermediary model to <code class=\"docutils literal notranslate\">Author</code>\nhappens only once, no single object of the joined models - i.e., a relation\nbetween one author and one entry - can fulfill the query condition (entries\nthat are co-authored by <code class=\"docutils literal notranslate\">anna</code> and <code class=\"docutils literal notranslate\">gloria</code>). You can circumvent this\nbehavior by chaining two consecutive <code class=\"docutils literal notranslate\">filter()</code> calls, resulting in two\nseparate joins and thus a more permissive filter:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>anna<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>filter<span class=\"p\">()</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>authors__name<span class=\"o\">=</span><span class=\"s2\">&quot;Gloria&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Entry: Supporting social movements with drums&gt;]&gt;</span>\n</code></pre></div>\n<aside class=\"admonition-exclude-is-also-sticky admonition\" role=\"note\">\n<p class=\"admonition-title\">exclude() is also sticky</p>\n<p>Please note that for this example,\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\">exclude()</code></a> behaves similarly\nto <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a> despite being\nimplemented differently. When traversing the many-to-many relationship,\nit does not exclude the entry <code class=\"docutils literal notranslate\">e</code> despite being co-authored by Gloria:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>anna<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>exclude<span class=\"p\">(</span>authors__name<span class=\"o\">=</span><span class=\"s2\">&quot;Gloria&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Entry: Supporting social movements with drums&gt;]&gt;</span>\n</code></pre></div>\n<p>When chaining a second <code class=\"docutils literal notranslate\">exclude()</code> call, an empty <code class=\"docutils literal notranslate\">QuerySet</code> is\nreturned, as expected:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>anna<span class=\"o\">.</span>entry_set<span class=\"o\">.</span>exclude<span class=\"p\">()</span><span class=\"o\">.</span>exclude<span class=\"p\">(</span>authors__name<span class=\"o\">=</span><span class=\"s2\">&quot;Gloria&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet []&gt;</span>\n</code></pre></div>\n<p>However, in other cases, <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\">exclude()</code></a>\nbehaves differently from <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a>.\nSee the <a class=\"reference internal\" href=\"#exclude-implementation\"><span class=\"std std-ref\">note</span></a> in the &quot;Spanning multi-valued\nrelationships&quot; section above.</p>\n</aside>\n</section>\n</section>\n<section id=\"one-to-one-relationships\">\n<h3>一对一关联<a class=\"heading-anchor\" href=\"#one-to-one-relationships\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>一对一关联与多对一关联非常类似。若在模型中定义了 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a>，该模型的实例只需通过其属性就能访问关联对象。</p>\n<p>例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">EntryDetail</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    entry <span class=\"o\">=</span> models<span class=\"o\">.</span>OneToOneField<span class=\"p\">(</span>Entry<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    details <span class=\"o\">=</span> models<span class=\"o\">.</span>TextField<span class=\"p\">()</span>\n\n\ned <span class=\"o\">=</span> EntryDetail<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\ned<span class=\"o\">.</span>entry  <span class=\"c1\"># Returns the related Entry object.</span>\n</code></pre></div>\n<p>不同点在于 “反向” 查询。一对一关联所关联的对象也能访问 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> 对象，但这个 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> 仅代表一个对象，而不是对象的集合:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>e <span class=\"o\">=</span> Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\ne<span class=\"o\">.</span>entrydetail  <span class=\"c1\"># returns the related EntryDetail object</span>\n</code></pre></div>\n<p>若未为关联关系指定对象，Django 会抛出 <code class=\"docutils literal notranslate\">DoesNotExist</code> 异常。</p>\n<p>实例能通过为正向关联指定关联对象一样的方式指定给反向关联:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>e<span class=\"o\">.</span>entrydetail <span class=\"o\">=</span> ed\n</code></pre></div>\n</section>\n<section id=\"how-are-the-backward-relationships-possible\">\n<h3>反向关联是如何实现的？<a class=\"heading-anchor\" href=\"#how-are-the-backward-relationships-possible\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>其它对象关联映射实现要求你在两边都定义关联关系。而 Django 开发者坚信这违反了 DRY 原则（不要自我重复），故 Django 仅要求你在一端定义关联关系。</p>\n<p>但这是如何实现的呢，给你一个模型类，模型类并不知道是否有其它模型类关联它，直到其它模型类被加载？</p>\n<p>The answer lies in the <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/applications/#django.apps.apps\" title=\"django.apps.apps\"><code class=\"xref py py-data docutils literal notranslate\">app registry</code></a>. When Django\nstarts, it imports each application listed in <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a>, and\nthen the <code class=\"docutils literal notranslate\">models</code> module inside each application. Whenever a new model class\nis created, Django adds backward-relationships to any related models. If the\nrelated models haven't been imported yet, Django keeps track of the\nrelationships and adds them when the related models eventually are imported.</p>\n<p>出于这个原因，包含你所使用的所有模型的应用必须列在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 中。否则，反向关联可能不会正常工作。</p>\n</section>\n<section id=\"queries-over-related-objects\">\n<h3>查询关联对象<a class=\"heading-anchor\" href=\"#queries-over-related-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>涉及关联对象的查询与涉及普通字段的查询遵守同样的规则。未查询条件指定值时，你可以使用对象实例，或该实例的主键。</p>\n<p>例如，若有个博客对象 <code class=\"docutils literal notranslate\">b</code>，其 <code class=\"docutils literal notranslate\">id=5</code>，以下三种查询是一样的:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Entry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog<span class=\"o\">=</span>b<span class=\"p\">)</span>  <span class=\"c1\"># Query using object instance</span>\nEntry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog<span class=\"o\">=</span>b<span class=\"o\">.</span>id<span class=\"p\">)</span>  <span class=\"c1\"># Query using id from instance</span>\nEntry<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>blog<span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span>  <span class=\"c1\"># Query using id directly</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"falling-back-to-raw-sql\">\n<h2>回归原生 SQL<a class=\"heading-anchor\" href=\"#falling-back-to-raw-sql\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>若你发现需要编写的 SQL 查询语句太过复杂，以至于 Django 的数据库映射无法处理，你可以回归手动编写 SQL。Django 针对编写原生 SQL 有几个选项；参考 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/db/sql/\"><span class=\"doc\">执行原生 SQL 查询</span></a>。</p>\n<p>最后，Django 数据库层只是一种访问数据库的接口，理解这点非常重要。你也可以通过其它工具，编程语言或数据库框架访问数据库；Django 并没有对数据库数据库做啥独有的操作。</p>\n</section>","rootId":"making-queries","toc":[{"title":"创建对象","anchor":"creating-objects","children":[]},{"title":"将修改保存至对象","anchor":"saving-changes-to-objects","children":[{"title":"保存 ForeignKey 和 ManyToManyField 字段","anchor":"saving-foreignkey-and-manytomanyfield-fields","children":[]}]},{"title":"检索对象","anchor":"retrieving-objects","children":[{"title":"检索全部对象","anchor":"retrieving-all-objects","children":[]},{"title":"通过过滤器检索指定对象","anchor":"retrieving-specific-objects-with-filters","children":[{"title":"链式过滤器","anchor":"chaining-filters","children":[]},{"title":"每个 QuerySet 都是唯一的","anchor":"filtered-querysets-are-unique","children":[]},{"title":"QuerySet 是惰性的","anchor":"querysets-are-lazy","children":[]}]},{"title":"用 get() 检索单个对象","anchor":"retrieving-a-single-object-with-get","children":[]},{"title":"其它 QuerySet 方法","anchor":"other-queryset-methods","children":[]},{"title":"限制 QuerySet 条目数","anchor":"limiting-querysets","children":[]},{"title":"字段查询","anchor":"field-lookups","children":[]},{"title":"跨关系查询","anchor":"lookups-that-span-relationships","children":[{"title":"跨多值关联","anchor":"spanning-multi-valued-relationships","children":[]}]},{"title":"过滤器可以为模型指定字段","anchor":"filters-can-reference-fields-on-the-model","children":[]},{"title":"表达式可以引用变换","anchor":"expressions-can-reference-transforms","children":[]},{"title":"主键 (pk) 查询快捷方式","anchor":"the-pk-lookup-shortcut","children":[]},{"title":"在 LIKE 语句中转义百分号和下划线","anchor":"escaping-percent-signs-and-underscores-in-like-statements","children":[]},{"title":"缓存和 QuerySet","anchor":"caching-and-querysets","children":[{"title":"当 QuerySet 未被缓存时","anchor":"when-querysets-are-not-cached","children":[]}]}]},{"title":"异步查询","anchor":"asynchronous-queries","children":[{"title":"查询迭代","anchor":"query-iteration","children":[]},{"title":"QuerySet 和管理器方法","anchor":"queryset-and-manager-methods","children":[]},{"title":"No deferred queries","anchor":"no-deferred-queries","children":[]},{"title":"事务","anchor":"transactions","children":[]}]},{"title":"查询 JSONField","anchor":"querying-jsonfield","children":[{"title":"保存和查询 None 值","anchor":"storing-and-querying-for-none","children":[]},{"title":"键、索引和路径转换","anchor":"key-index-and-path-transforms","children":[{"title":"KT() 表达式","anchor":"module-django.db.models.fields.json","children":[]}]},{"title":"包含与键查找","anchor":"containment-and-key-lookups","children":[{"title":"contains","anchor":"contains","children":[]},{"title":"contained_by","anchor":"contained-by","children":[]},{"title":"has_key","anchor":"has-key","children":[]},{"title":"has_keys","anchor":"has-keys","children":[]},{"title":"has_any_keys","anchor":"has-any-keys","children":[]}]}]},{"title":"通过 Q 对象完成复杂查询","anchor":"complex-lookups-with-q-objects","children":[]},{"title":"比较对象","anchor":"comparing-objects","children":[]},{"title":"删除对象","anchor":"deleting-objects","children":[]},{"title":"复制模型实例","anchor":"copying-model-instances","children":[]},{"title":"一次修改多个对象","anchor":"updating-multiple-objects-at-once","children":[]},{"title":"关联对象","anchor":"related-objects","children":[{"title":"一对多关联","anchor":"one-to-many-relationships","children":[{"title":"正向访问","anchor":"forward","children":[]},{"title":"“反向” 关联","anchor":"following-relationships-backward","children":[]},{"title":"使用自定义反向管理器","anchor":"using-a-custom-reverse-manager","children":[]},{"title":"管理关联对象的额外方法","anchor":"additional-methods-to-handle-related-objects","children":[]}]},{"title":"多对多关联","anchor":"many-to-many-relationships","children":[{"title":"Filtering on many-to-many relationships","anchor":"filtering-on-many-to-many-relationships","children":[]}]},{"title":"一对一关联","anchor":"one-to-one-relationships","children":[]},{"title":"反向关联是如何实现的？","anchor":"how-are-the-backward-relationships-possible","children":[]},{"title":"查询关联对象","anchor":"queries-over-related-objects","children":[]}]},{"title":"回归原生 SQL","anchor":"falling-back-to-raw-sql","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/6.1/topics/"},{"docname":"topics/db/index","title":"模型和数据库","url":"/zh-hans/6.1/topics/db/"}],"prev":{"docname":"topics/db/models","title":"模型","url":"/zh-hans/6.1/topics/db/models/"},"next":{"docname":"topics/db/fetch-modes","title":"Fetch modes","url":"/zh-hans/6.1/topics/db/fetch-modes/"},"formats":{"html":"/zh-hans/6.1/topics/db/queries/","markdown":"/zh-hans/6.1/topics/db/queries.md","json":"/zh-hans/6.1/topics/db/queries.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/topics/db/queries.txt","official":"https://docs.djangoproject.com/zh-hans/6.1/topics/db/queries/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}