{"title":"多对一关联","version":"2.2","locale":"zh-hans","docname":"topics/db/examples/many_to_one","url":"/zh-hans/2.2/topics/db/examples/many_to_one/","canonical":"https://djangodocs.dev/zh-hans/2.2/topics/db/examples/many_to_one/","summary":"要定义一个多对一关联，使用 ForeignKey : Code Copy from django.db import models class Reporter ( models . Model ): first_name = models . CharField ( max_length = 30 ) last_name =…","html":"<h1>多对一关联<a class=\"heading-anchor\" href=\"#many-to-one-relationships\"><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/2.2/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Reporter</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    <span class=\"n\">email</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">EmailField</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </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=\"s2\">&quot;</span><span class=\"si\">%s</span><span class=\"s2\"> </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">first_name</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">last_name</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Article</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">headline</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">pub_date</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n    <span class=\"n\">reporter</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ForeignKey</span><span class=\"p\">(</span><span class=\"n\">Reporter</span><span class=\"p\">,</span> <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </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><span class=\"n\">headline</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">ordering</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;headline&#39;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>下面是可以使用PythonAPI工具执行的操作示例。</p>\n<p>创建一些 Reporters：</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=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">Reporter</span><span class=\"p\">(</span><span class=\"n\">first_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">,</span> <span class=\"n\">last_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Smith&#39;</span><span class=\"p\">,</span> <span class=\"n\">email</span><span class=\"o\">=</span><span class=\"s1\">&#39;john@example.com&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r2</span> <span class=\"o\">=</span> <span class=\"n\">Reporter</span><span class=\"p\">(</span><span class=\"n\">first_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Paul&#39;</span><span class=\"p\">,</span> <span class=\"n\">last_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Jones&#39;</span><span class=\"p\">,</span> <span class=\"n\">email</span><span class=\"o\">=</span><span class=\"s1\">&#39;paul@example.com&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r2</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>创建一个 Article：</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=\"w\"> </span><span class=\"nn\">datetime</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">date</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">Article</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is a test&quot;</span><span class=\"p\">,</span> <span class=\"n\">pub_date</span><span class=\"o\">=</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">27</span><span class=\"p\">),</span> <span class=\"n\">reporter</span><span class=\"o\">=</span><span class=\"n\">r</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">id</span>\n<span class=\"go\">1</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">reporter</span>\n<span class=\"go\">&lt;Reporter: John Smith&gt;</span>\n</code></pre></div>\n<p>注意你必须先保存对象，然后再给它指定外键关系。比如，使用未保存的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Reporter</span></code> 创建 <code class=\"docutils literal notranslate\"><span class=\"pre\">Article</span></code> ，会引发 <code class=\"docutils literal notranslate\"><span class=\"pre\">ValueError</span></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=\"n\">r3</span> <span class=\"o\">=</span> <span class=\"n\">Reporter</span><span class=\"p\">(</span><span class=\"n\">first_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">,</span> <span class=\"n\">last_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Smith&#39;</span><span class=\"p\">,</span> <span class=\"n\">email</span><span class=\"o\">=</span><span class=\"s1\">&#39;john@example.com&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is a test&quot;</span><span class=\"p\">,</span> <span class=\"n\">pub_date</span><span class=\"o\">=</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">27</span><span class=\"p\">),</span> <span class=\"n\">reporter</span><span class=\"o\">=</span><span class=\"n\">r3</span><span class=\"p\">)</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n<span class=\"c\">...</span>\n<span class=\"gr\">ValueError</span>: <span class=\"n\">save() prohibited to prevent data loss due to unsaved related object &#39;reporter&#39;.</span>\n</code></pre></div>\n<p>Article 对象可以访问与它们相关联的 Reporter 对象：</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=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">reporter</span>\n</code></pre></div>\n<p>通过 Reporter 对象来创建一个 Article</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=\"n\">new_article</span> <span class=\"o\">=</span> <span class=\"n\">r</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;John&#39;s second story&quot;</span><span class=\"p\">,</span> <span class=\"n\">pub_date</span><span class=\"o\">=</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2005</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">29</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">new_article</span>\n<span class=\"go\">&lt;Article: John&#39;s second story&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">new_article</span><span class=\"o\">.</span><span class=\"n\">reporter</span>\n<span class=\"go\">&lt;Reporter: John Smith&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">new_article</span><span class=\"o\">.</span><span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">id</span>\n<span class=\"go\">1</span>\n</code></pre></div>\n<p>创建一个新的article：</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=\"n\">new_article2</span> <span class=\"o\">=</span> <span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;Paul&#39;s story&quot;</span><span class=\"p\">,</span> <span class=\"n\">pub_date</span><span class=\"o\">=</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2006</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">17</span><span class=\"p\">),</span> <span class=\"n\">reporter</span><span class=\"o\">=</span><span class=\"n\">r</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">new_article2</span><span class=\"o\">.</span><span class=\"n\">reporter</span>\n<span class=\"go\">&lt;Reporter: John Smith&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">new_article2</span><span class=\"o\">.</span><span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">id</span>\n<span class=\"go\">1</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: Paul&#39;s story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n</code></pre></div>\n<p>添加相同的article到一个不同的article集合，请观察它怎么移动：</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=\"n\">r2</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">new_article2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">new_article2</span><span class=\"o\">.</span><span class=\"n\">reporter</span><span class=\"o\">.</span><span class=\"n\">id</span>\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">new_article2</span><span class=\"o\">.</span><span class=\"n\">reporter</span>\n<span class=\"go\">&lt;Reporter: Paul Jones&gt;</span>\n</code></pre></div>\n<p>添加错误类型的对象，会引发TypeError：</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=\"n\">r</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">r2</span><span class=\"p\">)</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n<span class=\"c\">...</span>\n<span class=\"gr\">TypeError</span>: <span class=\"n\">&#39;Article&#39; instance expected, got &lt;Reporter: Paul Jones&gt;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r2</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: Paul&#39;s story&gt;]&gt;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">2</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r2</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">1</span>\n</code></pre></div>\n<p>注意在最后的例子里，那篇 article 的 reporter 已经从 John 变为 Paul。</p>\n<p>相关管理器也提供字段查询。只要你需要，API会自动跟踪关系，使用双下划线来分隔，你可以根据需要获取深层关系。这没有限制。比如：</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=\"n\">r</span><span class=\"o\">.</span><span class=\"n\">article_set</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">headline__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;This&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: This is a test&gt;]&gt;</span>\n\n<span class=\"go\"># Find all Articles for any Reporter whose first name is &quot;John&quot;.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter__first_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&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><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter__first_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n</code></pre></div>\n<p>在相关字段上查询两次。这里转化成WHERE从句里的AND条件。</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=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter__first_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">,</span> <span class=\"n\">reporter__last_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Smith&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&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><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter__pk</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter</span><span class=\"o\">=</span><span class=\"n\">r</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter__in</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">])</span><span class=\"o\">.</span><span class=\"n\">distinct</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: Paul&#39;s story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter__in</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">r</span><span class=\"p\">,</span><span class=\"n\">r2</span><span class=\"p\">])</span><span class=\"o\">.</span><span class=\"n\">distinct</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: Paul&#39;s story&gt;, &lt;Article: This is a test&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><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">reporter__in</span><span class=\"o\">=</span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">first_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">distinct</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&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><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__pk</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article</span><span class=\"o\">=</span><span class=\"n\">a</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__headline__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;This&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;, &lt;Reporter: John Smith&gt;, &lt;Reporter: John Smith&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__headline__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;This&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">distinct</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;</span>\n</code></pre></div>\n<p>反向查询的计数与 distinct() ：</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=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__headline__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;This&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">3</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__headline__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;This&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">distinct</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">1</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=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__reporter__first_name__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;, &lt;Reporter: John Smith&gt;, &lt;Reporter: John Smith&gt;, &lt;Reporter: John Smith&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__reporter__first_name__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;John&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">distinct</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__reporter</span><span class=\"o\">=</span><span class=\"n\">r</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">distinct</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;</span>\n</code></pre></div>\n<p>如果删除了一个reporter，他的articles将被删除（假设使用设置了 <code class=\"docutils literal notranslate\"><span class=\"pre\">CASCADE</span></code> 的 <a class=\"reference internal\" href=\"/zh-hans/2.2/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\"><span class=\"pre\">django.db.models.ForeignKey.on_delete</span></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=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: Paul&#39;s story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;first_name&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;, &lt;Reporter: Paul Jones&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">r2</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Article: John&#39;s second story&gt;, &lt;Article: This is a test&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;first_name&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;</span>\n</code></pre></div>\n<p>可以在查询中使用JOIN进行删除：</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=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">article__headline__startswith</span><span class=\"o\">=</span><span class=\"s1\">&#39;This&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Reporter</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet []&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Article</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet []&gt;</span>\n</code></pre></div>","rootId":"many-to-one-relationships","toc":[],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/2.2/topics/"},{"docname":"topics/db/index","title":"模型和数据库","url":"/zh-hans/2.2/topics/db/"},{"docname":"topics/db/examples/index","title":"模型关联 API 用法示例","url":"/zh-hans/2.2/topics/db/examples/"}],"prev":{"docname":"topics/db/examples/many_to_many","title":"多对多关联","url":"/zh-hans/2.2/topics/db/examples/many_to_many/"},"next":{"docname":"topics/db/examples/one_to_one","title":"一对一关联","url":"/zh-hans/2.2/topics/db/examples/one_to_one/"},"formats":{"html":"/zh-hans/2.2/topics/db/examples/many_to_one/","markdown":"/zh-hans/2.2/topics/db/examples/many_to_one.md","json":"/zh-hans/2.2/topics/db/examples/many_to_one.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/topics/db/examples/many_to_one.txt","official":"https://docs.djangoproject.com/zh-hans/2.2/topics/db/examples/many_to_one/","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","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}