{"title":"管理器","version":"3.0","locale":"zh-hans","docname":"topics/db/managers","url":"/zh-hans/3.0/topics/db/managers/","canonical":"https://djangodocs.dev/zh-hans/3.0/topics/db/managers/","summary":"class Manager Link to this definition # Manager 是一种接口，它赋予了 Django 模型操作数据库的能力。Django 应用中每个模型拥有至少一个 Manager 。 Manager 类的文档介绍位于 执行查询 ；本页着重介绍自定义 Manager 行为的模型选项。 管理器名称…","html":"<h1>管理器<a class=\"heading-anchor\" href=\"#managers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Manager\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Manager</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Manager\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 是一种接口，它赋予了 Django 模型操作数据库的能力。Django 应用中每个模型拥有至少一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 类的文档介绍位于 <a class=\"reference internal\" href=\"/zh-hans/3.0/topics/db/queries/\"><span class=\"doc\">执行查询</span></a>；本页着重介绍自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 行为的模型选项。</p>\n<section id=\"manager-names\">\n<span id=\"id1\"></span><h2>管理器名称<a class=\"heading-anchor\" href=\"#manager-names\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>默认情况下，Django 为每个模型类添加了一个名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> 的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>。不过，若你想将 <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> 用作字段名，或想使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> 以外的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 名字，就要在模型基类中重命名。要为指定类重命名 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>，在该模型中定义一个类型为 <code class=\"docutils literal notranslate\"><span class=\"pre\">models.Manager</span></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=\"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\">Person</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=\"c1\">#...</span>\n    <span class=\"n\">people</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>使用这个实例模型时， <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.objects</span></code> 会产生一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">AttributeError</span></code> 异常，而 <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.people.all()</span></code> 会返回包含所有 <code class=\"docutils literal notranslate\"><span class=\"pre\">Person</span></code> 对象的列表。</p>\n</section>\n<section id=\"custom-managers\">\n<span id=\"id2\"></span><h2>自定义管理器<a class=\"heading-anchor\" href=\"#custom-managers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>继承基类 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>，在模型中实例化自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>，你就可以在该模型中使用自定义的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>。</p>\n<p>有两种原因可能使你想要自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>：添加额外的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 方法，修改 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 返回的原始 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>。</p>\n<section id=\"adding-extra-manager-methods\">\n<h3>添加额外的管理器方法<a class=\"heading-anchor\" href=\"#adding-extra-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\"><span class=\"pre\">Manager</span></code> 方法一般是为模型添加 “表级” 功能的更好方法。（对于 “行级” 功能 —— 即，只操作单个模型对象 —— 通过 <a class=\"reference internal\" href=\"/zh-hans/3.0/topics/db/models/#model-methods\"><span class=\"std std-ref\">模型方法</span></a>，而不是自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 的方法。）</p>\n<p>自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 方法能返回任何东西，没有强制它必须返回一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>。</p>\n<p>例如，这个自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 提供了一个方法 <code class=\"docutils literal notranslate\"><span class=\"pre\">with_counts()</span></code>，它会返回包含所有 <code class=\"docutils literal notranslate\"><span class=\"pre\">OpinionPoll</span></code> 对象的列表。每个对象都有一个额外属性 <code class=\"docutils literal notranslate\"><span class=\"pre\">num_response</span></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=\"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\">PollManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">with_counts</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <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\">connection</span>\n        <span class=\"k\">with</span> <span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">()</span> <span class=\"k\">as</span> <span class=\"n\">cursor</span><span class=\"p\">:</span>\n            <span class=\"n\">cursor</span><span class=\"o\">.</span><span class=\"n\">execute</span><span class=\"p\">(</span><span class=\"s2\">&quot;&quot;&quot;</span>\n<span class=\"s2\">                SELECT p.id, p.question, p.poll_date, COUNT(*)</span>\n<span class=\"s2\">                FROM polls_opinionpoll p, polls_response r</span>\n<span class=\"s2\">                WHERE p.id = r.poll_id</span>\n<span class=\"s2\">                GROUP BY p.id, p.question, p.poll_date</span>\n<span class=\"s2\">                ORDER BY p.poll_date DESC&quot;&quot;&quot;</span><span class=\"p\">)</span>\n            <span class=\"n\">result_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"k\">for</span> <span class=\"n\">row</span> <span class=\"ow\">in</span> <span class=\"n\">cursor</span><span class=\"o\">.</span><span class=\"n\">fetchall</span><span class=\"p\">():</span>\n                <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"n\">row</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">question</span><span class=\"o\">=</span><span class=\"n\">row</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">poll_date</span><span class=\"o\">=</span><span class=\"n\">row</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">])</span>\n                <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">num_responses</span> <span class=\"o\">=</span> <span class=\"n\">row</span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">]</span>\n                <span class=\"n\">result_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">result_list</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">OpinionPoll</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\">question</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\">200</span><span class=\"p\">)</span>\n    <span class=\"n\">poll_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\">objects</span> <span class=\"o\">=</span> <span class=\"n\">PollManager</span><span class=\"p\">()</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Response</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\">poll</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\">OpinionPoll</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    <span class=\"n\">person_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\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">TextField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>通过本例，你可以利用 <code class=\"docutils literal notranslate\"><span class=\"pre\">OpinionPoll.objects.with_counts()</span></code> 返回一个包含 <code class=\"docutils literal notranslate\"><span class=\"pre\">OpinionPoll</span></code> 对象的列表，每个对象都有 <code class=\"docutils literal notranslate\"><span class=\"pre\">num_responses</span></code> 属性。</p>\n<p>本例的另一个注意事项是 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 方法能通过 <code class=\"docutils literal notranslate\"><span class=\"pre\">self.model</span></code> 获取所依附的模型类。</p>\n</section>\n<section id=\"modifying-a-manager-s-initial-queryset\">\n<h3>修改管理器的初始 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code><a class=\"heading-anchor\" href=\"#modifying-a-manager-s-initial-queryset\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 的基础 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></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=\"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\">Book</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\">title</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\">author</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\">50</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>……语句 <code class=\"docutils literal notranslate\"><span class=\"pre\">Book.objects.all()</span></code> 会返回数据库中所有的书。</p>\n<p>你可以通过重写 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager.get_queryset()</span></code> 方法来覆盖 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 的基础 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>。 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> 返回的 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 应该包含你需要的属性。</p>\n<p>例如，以下模型有 <em>两个</em> <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> —— 一个返回所有对象，另一个仅返回 Roald Dahl 写的书:</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\"># First, define the Manager subclass.</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">DahlBookManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_queryset</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">author</span><span class=\"o\">=</span><span class=\"s1\">&#39;Roald Dahl&#39;</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Then hook it into the Book model explicitly.</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Book</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\">title</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\">author</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\">50</span><span class=\"p\">)</span>\n\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">()</span> <span class=\"c1\"># The default manager.</span>\n    <span class=\"n\">dahl_objects</span> <span class=\"o\">=</span> <span class=\"n\">DahlBookManager</span><span class=\"p\">()</span> <span class=\"c1\"># The Dahl-specific manager.</span>\n</code></pre></div>\n<p>使用这个实例模型时， <code class=\"docutils literal notranslate\"><span class=\"pre\">Book.objects.all()</span></code> 会返回数据库中所有的书，而 <code class=\"docutils literal notranslate\"><span class=\"pre\">Book.dahl_objects.all()</span></code> 仅返回 Roald Dahl 写的书。</p>\n<p>当然，因为 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> 返回一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 对象，你可以在上面调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code>， <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude()</span></code> 和其它的 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></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=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">dahl_objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n<span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">dahl_objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"o\">=</span><span class=\"s1\">&#39;Matilda&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">dahl_objects</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>本例同时介绍了另一个有趣的技巧：在一个模型中使用多个管理器。你可以为一个模型添加任意多个 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager()</span></code>。为模型定义通用 &quot;filters&quot; 的非重复方式。</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=\"w\"> </span><span class=\"nc\">AuthorManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_queryset</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">role</span><span class=\"o\">=</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">EditorManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_queryset</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">role</span><span class=\"o\">=</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</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\">50</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\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">role</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\">1</span><span class=\"p\">,</span> <span class=\"n\">choices</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">,</span> <span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Author&#39;</span><span class=\"p\">)),</span> <span class=\"p\">(</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">,</span> <span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Editor&#39;</span><span class=\"p\">))])</span>\n    <span class=\"n\">people</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">()</span>\n    <span class=\"n\">authors</span> <span class=\"o\">=</span> <span class=\"n\">AuthorManager</span><span class=\"p\">()</span>\n    <span class=\"n\">editors</span> <span class=\"o\">=</span> <span class=\"n\">EditorManager</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>本例允许你调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.authors.all()</span></code>， <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.editors.all()</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.people.all()</span></code>，返回符合期望的结果。</p>\n</section>\n<section id=\"default-managers\">\n<span id=\"id3\"></span><h3>默认管理器<a class=\"heading-anchor\" href=\"#default-managers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model._default_manager\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">_default_manager</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Model._default_manager\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>若你使用自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 对象，注意 Django 遇到的第一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> （按照你在模型中定义的顺序）会拥有一个独特的状态。Django 将类定义中的第一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 视作 “默认” <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>，Django 的几个组件（包括 <a class=\"reference internal\" href=\"/zh-hans/3.0/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">dumpdata</span></code></a>）在用到该模型时会独立地调用该 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>。故此，选择默认管理器时要万分小心，避免遇到重写的 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> 无法获取期望的结果这种情况。</p>\n<p>你可以通过 <a class=\"reference internal\" href=\"/zh-hans/3.0/ref/models/options/#django.db.models.Options.default_manager_name\" title=\"django.db.models.Options.default_manager_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">Meta.default_manager_name</span></code></a> 指定一个自定义的默认管理器。</p>\n<p>若你正在编写的代码必须处理未知模型，例如，在实现了通用视图的第三方应用中使用这个管理器（或 <a class=\"reference internal\" href=\"#django.db.models.Model._base_manager\" title=\"django.db.models.Model._base_manager\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">_base_manager</span></code></a>），而不是假定该模型有一个名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> 的管理器。</p>\n</section>\n<section id=\"base-managers\">\n<h3>基础管理器<a class=\"heading-anchor\" href=\"#base-managers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model._base_manager\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">_base_manager</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Model._base_manager\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<section id=\"using-managers-for-related-object-access\">\n<span id=\"managers-for-related-objects\"></span><h4>用于访问关联对象的管理器<a class=\"heading-anchor\" href=\"#using-managers-for-related-object-access\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>默认情况下，Django 访问关联对象（即 <code class=\"docutils literal notranslate\"><span class=\"pre\">choice.question</span></code>）时使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">Model._base_manager</span></code> 管理器类的实例，而不是关联对象的 <code class=\"docutils literal notranslate\"><span class=\"pre\">_default_manager</span></code>。这是因为 Django 要检索那些可能被默认管理器筛选掉（所以无法访问）的关联对象。</p>\n<p>若基本管理器类 (<a class=\"reference internal\" href=\"#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.db.models.Manager</span></code></a>) 无法满足需求，你可以通过设置 <a class=\"reference internal\" href=\"/zh-hans/3.0/ref/models/options/#django.db.models.Options.base_manager_name\" title=\"django.db.models.Options.base_manager_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">Meta.base_manager_name</span></code></a> 告诉 Django 使用哪个类。</p>\n<p>在关联模型上执行查询时不会使用基础管理器，或者当访问一对多或多对多关系( <a class=\"reference internal\" href=\"/zh-hans/3.0/topics/db/queries/#backwards-related-objects\"><span class=\"std std-ref\">accessing a one-to-many or many-to-many relationship</span></a> )。例如，若 <a class=\"reference internal\" href=\"/zh-hans/3.0/intro/tutorial02/#creating-models\"><span class=\"std std-ref\">来自教程</span></a> 的模型 <code class=\"docutils literal notranslate\"><span class=\"pre\">Question</span></code> 有个 <code class=\"docutils literal notranslate\"><span class=\"pre\">deleted</span></code> 字段，还有一个基础管理器，用于筛选出 <code class=\"docutils literal notranslate\"><span class=\"pre\">deleted=True</span></code> 的实例。由 <code class=\"docutils literal notranslate\"><span class=\"pre\">Choice.objects.filter(question__name__startswith='What')</span></code> 返回的查询结果集会包含关联至已删除的问题的选项。</p>\n</section>\n<section id=\"don-t-filter-away-any-results-in-this-type-of-manager-subclass\">\n<h4>不要在这类管理器子类中过滤掉任何结果<a class=\"heading-anchor\" href=\"#don-t-filter-away-any-results-in-this-type-of-manager-subclass\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>该管理器用于访问由其它模型关联过来的对象。这些情况下，Django 要能访问待获取模型的全部对象，这样就能检索出其指向的 <em>任何东西</em>。</p>\n<p>若你重写了 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> 方法，并筛掉了全部行，Django 会返回错误的结果。所以，不要这么做。会筛选 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> 的管理器并不适合用作基础管理器。</p>\n</section>\n</section>\n<section id=\"calling-custom-queryset-methods-from-the-manager\">\n<span id=\"calling-custom-queryset-methods-from-manager\"></span><h3>管理器调用自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 方法<a class=\"heading-anchor\" href=\"#calling-custom-queryset-methods-from-the-manager\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>因为大部分的标准 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 方法能直接从 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 访问，这个实例仅适用于你在自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 中定义了额外方法，且在 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></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=\"w\"> </span><span class=\"nc\">PersonQuerySet</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">QuerySet</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">authors</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\">filter</span><span class=\"p\">(</span><span class=\"n\">role</span><span class=\"o\">=</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">editors</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\">filter</span><span class=\"p\">(</span><span class=\"n\">role</span><span class=\"o\">=</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PersonManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">PersonQuerySet</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"p\">,</span> <span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_db</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">authors</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\">get_queryset</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">authors</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">editors</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\">get_queryset</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">editors</span><span class=\"p\">()</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</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\">50</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\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">role</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\">1</span><span class=\"p\">,</span> <span class=\"n\">choices</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">,</span> <span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Author&#39;</span><span class=\"p\">)),</span> <span class=\"p\">(</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">,</span> <span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Editor&#39;</span><span class=\"p\">))])</span>\n    <span class=\"n\">people</span> <span class=\"o\">=</span> <span class=\"n\">PersonManager</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>本例允许你从管理器 <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.people</span></code> 直接调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">authors()</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">editors()</span></code>。</p>\n</section>\n<section id=\"creating-a-manager-with-queryset-methods\">\n<span id=\"create-manager-with-queryset-methods\"></span><h3>创建带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 方法的管理器<a class=\"heading-anchor\" href=\"#creating-a-manager-with-queryset-methods\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>要替换前面的要求复制 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>  方法的方案， 可以用 <a class=\"reference internal\" href=\"/zh-hans/3.0/ref/models/querysets/#django.db.models.query.QuerySet.as_manager\" title=\"django.db.models.query.QuerySet.as_manager\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">QuerySet.as_manager()</span></code></a> 创建一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 实例，拷贝了自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></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=\"w\"> </span><span class=\"nc\">Person</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=\"o\">...</span>\n    <span class=\"n\">people</span> <span class=\"o\">=</span> <span class=\"n\">PersonQuerySet</span><span class=\"o\">.</span><span class=\"n\">as_manager</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>由 <a class=\"reference internal\" href=\"/zh-hans/3.0/ref/models/querysets/#django.db.models.query.QuerySet.as_manager\" title=\"django.db.models.query.QuerySet.as_manager\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">QuerySet.as_manager()</span></code></a> 创建的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 实例实质上等价于前面例子中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">PersonManager</span></code>。</p>\n<p>不是每个 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 方法在 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 层都是有意义的；例如，我们故意阻止 <a class=\"reference internal\" href=\"/zh-hans/3.0/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\"><span class=\"pre\">QuerySet.delete()</span></code></a> 被拷贝进 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 类中。</p>\n<p>方法拷贝规则如下：</p>\n<ul class=\"simple\">\n<li><p>公开方法默认会被拷贝。</p></li>\n<li><p>私有方法（以下划线打头）默认不会被复制。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">queryset_only</span></code> 属性值为 <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> 的方法总是会被复制。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">queryset_only</span></code> 属性值为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></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><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomQuerySet</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">QuerySet</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Available on both Manager and QuerySet.</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">public_method</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span>\n\n    <span class=\"c1\"># Available only on QuerySet.</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">_private_method</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span>\n\n    <span class=\"c1\"># Available only on QuerySet.</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">opted_out_public_method</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span>\n    <span class=\"n\">opted_out_public_method</span><span class=\"o\">.</span><span class=\"n\">queryset_only</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n    <span class=\"c1\"># Available on both Manager and QuerySet.</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">_opted_in_private_method</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span>\n    <span class=\"n\">_opted_in_private_method</span><span class=\"o\">.</span><span class=\"n\">queryset_only</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n</code></pre></div>\n<section id=\"from-queryset\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">from_queryset()</span></code><a class=\"heading-anchor\" href=\"#from-queryset\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.from_queryset\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">classmethod</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">from_queryset</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">queryset_class</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.from_queryset\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>对于进阶用法，你可能同时要一个自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 和一个自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>。你可以通过调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager.from_queryset()</span></code> 达成目的，这将会返回一个自定义基础 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 的子类，带有一份自定义 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></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=\"w\"> </span><span class=\"nc\">CustomManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">manager_only_method</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomQuerySet</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">QuerySet</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">manager_and_queryset_method</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</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\">objects</span> <span class=\"o\">=</span> <span class=\"n\">CustomManager</span><span class=\"o\">.</span><span class=\"n\">from_queryset</span><span class=\"p\">(</span><span class=\"n\">CustomQuerySet</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><span class=\"n\">MyManager</span> <span class=\"o\">=</span> <span class=\"n\">CustomManager</span><span class=\"o\">.</span><span class=\"n\">from_queryset</span><span class=\"p\">(</span><span class=\"n\">CustomQuerySet</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</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\">objects</span> <span class=\"o\">=</span> <span class=\"n\">MyManager</span><span class=\"p\">()</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"custom-managers-and-model-inheritance\">\n<span id=\"custom-managers-and-inheritance\"></span><h3>自定义管理器和模型继承<a class=\"heading-anchor\" href=\"#custom-managers-and-model-inheritance\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>下面是 Django 如何处理自定义管理器和 <a class=\"reference internal\" href=\"/zh-hans/3.0/topics/db/models/#model-inheritance\"><span class=\"std std-ref\">模型继承</span></a>：</p>\n<ol class=\"arabic simple\">\n<li><p>基类的管理器总是被子类以 Python 的普通名称解析顺序继承（子类上的属性会覆盖所有父类上的同名属性；直接父类会覆盖更上一级的，以此类推）。</p></li>\n<li><p>如果没有在模型或其父类申明管理器，Django 会自动创建 <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> 管理器。</p></li>\n<li><p>一个类的默认管理器要么由 <a class=\"reference internal\" href=\"/zh-hans/3.0/ref/models/options/#django.db.models.Options.default_manager_name\" title=\"django.db.models.Options.default_manager_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">Meta.default_manager_name</span></code></a> 指定，要么是模型中申明的第一个管理器，或者是直接父模型的默认管理器。</p></li>\n</ol>\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=\"w\"> </span><span class=\"nc\">AbstractBase</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=\"c1\"># ...</span>\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">CustomManager</span><span class=\"p\">()</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\">abstract</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>如果您在子类中直接使用这一点，如果您在基类中没有声明任何管理器，那么 <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></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=\"w\"> </span><span class=\"nc\">ChildA</span><span class=\"p\">(</span><span class=\"n\">AbstractBase</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"c1\"># This class has CustomManager as the default manager.</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n<p>如果您想继承 <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractBase</span></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=\"w\"> </span><span class=\"nc\">ChildB</span><span class=\"p\">(</span><span class=\"n\">AbstractBase</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"c1\"># An explicit default manager.</span>\n    <span class=\"n\">default_manager</span> <span class=\"o\">=</span> <span class=\"n\">OtherManager</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>这里的 <code class=\"docutils literal notranslate\"><span class=\"pre\">default_manager</span></code> 是默认的。 <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> 管理器仍然可用，因为它是继承的，但没有被当做默认管理器。</p>\n<p>最后，对于这个示例，假设您想要向子类中添加额外的管理器，但是仍然使用来自 <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractBase</span></code> 的默认管理器。您不能直接在子类中添加新的管理器，因为这将覆盖默认管理器，并且您还必须显式地申明来自抽象基类的所有管理器。解决方案是将这个管理器放到另一个基类中，并在默认管理器 <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><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ExtraManager</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\">extra_manager</span> <span class=\"o\">=</span> <span class=\"n\">OtherManager</span><span class=\"p\">()</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\">abstract</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ChildC</span><span class=\"p\">(</span><span class=\"n\">AbstractBase</span><span class=\"p\">,</span> <span class=\"n\">ExtraManager</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"c1\"># Default manager is CustomManager, but OtherManager is</span>\n    <span class=\"c1\"># also available via the &quot;extra_manager&quot; attribute.</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n<p>请注意，虽然可以在抽象模型上 <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><span class=\"n\">ClassA</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">do_something</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><span class=\"n\">AbstractBase</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">do_something</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>会引发一个异常。这是因为管理器意在封装管理映射对象集合的逻辑。因为您不能拥有抽象对象的集合，所以管理抽象对象是没有意义的。如果您有适用于抽象模型的功能，则应该将该功能放在抽象模型的 <code class=\"docutils literal notranslate\"><span class=\"pre\">静态方法</span></code> 或 <code class=\"docutils literal notranslate\"><span class=\"pre\">类方法</span></code> 中。</p>\n</section>\n<section id=\"implementation-concerns\">\n<h3>执行关系<a class=\"heading-anchor\" href=\"#implementation-concerns\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>无论您在自定义的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 中添加了什么特性，都必须能够对 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">copy</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">manager</span> <span class=\"o\">=</span> <span class=\"n\">MyManager</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">my_copy</span> <span class=\"o\">=</span> <span class=\"n\">copy</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">(</span><span class=\"n\">manager</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Django 在某些查询期间对管理器对象进行浅拷贝；如果您的管理器无法被复制，那么这些查询将失败。</p>\n<p>对于大多数的资源管理器来说，这不是问题。若你只是为 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 添加简单的方法，一般不会疏忽地把 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 变的不可拷贝。但是，若重写了 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 对象用于控制对象状态的 <code class=\"docutils literal notranslate\"><span class=\"pre\">__getattr__</span></code> 或其它私有方法，你需要确认你的修改不会影响 <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> 被复制。</p>\n</section>\n</section>","rootId":"managers","toc":[{"title":"管理器名称","anchor":"manager-names","children":[]},{"title":"自定义管理器","anchor":"custom-managers","children":[{"title":"添加额外的管理器方法","anchor":"adding-extra-manager-methods","children":[]},{"title":"修改管理器的初始 QuerySet","anchor":"modifying-a-manager-s-initial-queryset","children":[]},{"title":"默认管理器","anchor":"default-managers","children":[]},{"title":"基础管理器","anchor":"base-managers","children":[{"title":"用于访问关联对象的管理器","anchor":"using-managers-for-related-object-access","children":[]},{"title":"不要在这类管理器子类中过滤掉任何结果","anchor":"don-t-filter-away-any-results-in-this-type-of-manager-subclass","children":[]}]},{"title":"管理器调用自定义 QuerySet 方法","anchor":"calling-custom-queryset-methods-from-the-manager","children":[]},{"title":"创建带有 QuerySet 方法的管理器","anchor":"creating-a-manager-with-queryset-methods","children":[{"title":"from_queryset()","anchor":"from-queryset","children":[]}]},{"title":"自定义管理器和模型继承","anchor":"custom-managers-and-model-inheritance","children":[]},{"title":"执行关系","anchor":"implementation-concerns","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/3.0/topics/"},{"docname":"topics/db/index","title":"模型和数据库","url":"/zh-hans/3.0/topics/db/"}],"prev":{"docname":"topics/db/search","title":"搜索","url":"/zh-hans/3.0/topics/db/search/"},"next":{"docname":"topics/db/sql","title":"执行原生 SQL 查询","url":"/zh-hans/3.0/topics/db/sql/"},"formats":{"html":"/zh-hans/3.0/topics/db/managers/","markdown":"/zh-hans/3.0/topics/db/managers.md","json":"/zh-hans/3.0/topics/db/managers.json"},"source":"https://github.com/django/django/blob/stable/3.0.x/docs/topics/db/managers.txt","official":"https://docs.djangoproject.com/zh-hans/3.0/topics/db/managers/","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"]}