{"title":"管理器","version":"2.2","locale":"zh-hans","docname":"topics/db/managers","url":"/zh-hans/2.2/topics/db/managers/","canonical":"https://djangodocs.dev/zh-hans/2.2/topics/db/managers/","summary":"Manager 是一种接口，它赋予了 Django 模型操作数据库的能力。Django 应用中每个模型拥有至少一个 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\">class</span> </em><span class=\"sig-name descname\">Manager</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\">Manager</code> 是一种接口，它赋予了 Django 模型操作数据库的能力。Django 应用中每个模型拥有至少一个 <code class=\"docutils literal notranslate\">Manager</code>。</p>\n<p><code class=\"docutils literal notranslate\">Manager</code> 类的文档介绍位于 <a class=\"reference internal\" href=\"/zh-hans/2.2/topics/db/queries/\"><span class=\"doc\">执行查询</span></a>；本页着重介绍自定义 <code class=\"docutils literal notranslate\">Manager</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\">objects</code> 的 <code class=\"docutils literal notranslate\">Manager</code>。不过，若你想将 <code class=\"docutils literal notranslate\">objects</code> 用作字段名，或想使用 <code class=\"docutils literal notranslate\">objects</code> 以外的 <code class=\"docutils literal notranslate\">Manager</code> 名字，就要在模型基类中重命名。要为指定类重命名 <code class=\"docutils literal notranslate\">Manager</code>，在该模型中定义一个类型为 <code class=\"docutils literal notranslate\">models.Manager</code> 的属性。例如:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">Person</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\">#...</span>\n    people <span class=\"o\">=</span> models<span class=\"o\">.</span>Manager<span class=\"p\">()</span>\n</code></pre></div>\n<p>使用这个实例模型时， <code class=\"docutils literal notranslate\">Person.objects</code> 会产生一个 <code class=\"docutils literal notranslate\">AttributeError</code> 异常，而 <code class=\"docutils literal notranslate\">Person.people.all()</code> 会返回包含所有 <code class=\"docutils literal notranslate\">Person</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\">Manager</code>，在模型中实例化自定义 <code class=\"docutils literal notranslate\">Manager</code>，你就可以在该模型中使用自定义的 <code class=\"docutils literal notranslate\">Manager</code>。</p>\n<p>有两种原因可能使你想要自定义 <code class=\"docutils literal notranslate\">Manager</code>：添加额外的 <code class=\"docutils literal notranslate\">Manager</code> 方法，修改 <code class=\"docutils literal notranslate\">Manager</code> 返回的原始 <code class=\"docutils literal notranslate\">QuerySet</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\">Manager</code> 方法一般是为模型添加 “表级” 功能的更好方法。（对于 “行级” 功能 —— 即，只操作单个模型对象 —— 通过 <a class=\"reference internal\" href=\"/zh-hans/2.2/topics/db/models/#model-methods\"><span class=\"std std-ref\">模型方法</span></a>，而不是自定义 <code class=\"docutils literal notranslate\">Manager</code> 的方法。）</p>\n<p>自定义 <code class=\"docutils literal notranslate\">Manager</code> 方法能返回任何东西，没有强制它必须返回一个 <code class=\"docutils literal notranslate\">QuerySet</code>。</p>\n<p>例如，这个自定义 <code class=\"docutils literal notranslate\">Manager</code> 提供了一个方法 <code class=\"docutils literal notranslate\">with_counts()</code>，它会返回包含所有 <code class=\"docutils literal notranslate\">OpinionPoll</code> 对象的列表。每个对象都有一个额外属性 <code class=\"docutils literal notranslate\">num_response</code>，这是一次聚合查询的结果:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">PollManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Manager<span class=\"p\">):</span>\n    <span class=\"k\">def</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=\"nn\">django.db</span> <span class=\"kn\">import</span> connection\n        <span class=\"k\">with</span> connection<span class=\"o\">.</span>cursor<span class=\"p\">()</span> <span class=\"k\">as</span> cursor<span class=\"p\">:</span>\n            cursor<span class=\"o\">.</span>execute<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            result_list <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"k\">for</span> row <span class=\"ow\">in</span> cursor<span class=\"o\">.</span>fetchall<span class=\"p\">():</span>\n                p <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span>model<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span>row<span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> question<span class=\"o\">=</span>row<span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> poll_date<span class=\"o\">=</span>row<span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">])</span>\n                p<span class=\"o\">.</span>num_responses <span class=\"o\">=</span> row<span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">]</span>\n                result_list<span class=\"o\">.</span>append<span class=\"p\">(</span>p<span class=\"p\">)</span>\n        <span class=\"k\">return</span> result_list\n\n<span class=\"k\">class</span> <span class=\"nc\">OpinionPoll</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    question <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    poll_date <span class=\"o\">=</span> models<span class=\"o\">.</span>DateField<span class=\"p\">()</span>\n    objects <span class=\"o\">=</span> PollManager<span class=\"p\">()</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Response</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    poll <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>OpinionPoll<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    person_name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    response <span class=\"o\">=</span> models<span class=\"o\">.</span>TextField<span class=\"p\">()</span>\n</code></pre></div>\n<p>通过本例，你可以利用 <code class=\"docutils literal notranslate\">OpinionPoll.objects.with_counts()</code> 返回一个包含 <code class=\"docutils literal notranslate\">OpinionPoll</code> 对象的列表，每个对象都有 <code class=\"docutils literal notranslate\">num_responses</code> 属性。</p>\n<p>本例的另一个注意事项是 <code class=\"docutils literal notranslate\">Manager</code> 方法能通过 <code class=\"docutils literal notranslate\">self.model</code> 获取所依附的模型类。</p>\n</section>\n<section id=\"modifying-a-manager-s-initial-queryset\">\n<h3>修改管理器的初始 <code class=\"docutils literal notranslate\">QuerySet</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\">Manager</code> 的基础 <code class=\"docutils literal notranslate\">QuerySet</code> 会返回系统中所有的对象。例如，使用以下模型:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">Book</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    title <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    author <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>……语句 <code class=\"docutils literal notranslate\">Book.objects.all()</code> 会返回数据库中所有的书。</p>\n<p>你可以通过重写 <code class=\"docutils literal notranslate\">Manager.get_queryset()</code> 方法来覆盖 <code class=\"docutils literal notranslate\">Manager</code> 的基础 <code class=\"docutils literal notranslate\">QuerySet</code>。 <code class=\"docutils literal notranslate\">get_queryset()</code> 返回的 <code class=\"docutils literal notranslate\">QuerySet</code> 应该包含你需要的属性。</p>\n<p>例如，以下模型有 <em>两个</em> <code class=\"docutils literal notranslate\">Manager</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=\"nc\">DahlBookManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Manager<span class=\"p\">):</span>\n    <span class=\"k\">def</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>get_queryset<span class=\"p\">()</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>author<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=\"nc\">Book</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    title <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    author <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n\n    objects <span class=\"o\">=</span> models<span class=\"o\">.</span>Manager<span class=\"p\">()</span> <span class=\"c1\"># The default manager.</span>\n    dahl_objects <span class=\"o\">=</span> DahlBookManager<span class=\"p\">()</span> <span class=\"c1\"># The Dahl-specific manager.</span>\n</code></pre></div>\n<p>使用这个实例模型时， <code class=\"docutils literal notranslate\">Book.objects.all()</code> 会返回数据库中所有的书，而 <code class=\"docutils literal notranslate\">Book.dahl_objects.all()</code> 仅返回 Roald Dahl 写的书。</p>\n<p>当然，因为 <code class=\"docutils literal notranslate\">get_queryset()</code> 返回一个 <code class=\"docutils literal notranslate\">QuerySet</code> 对象，你可以在上面调用 <code class=\"docutils literal notranslate\">filter()</code>， <code class=\"docutils literal notranslate\">exclude()</code> 和其它的 <code class=\"docutils literal notranslate\">QuerySet</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>Book<span class=\"o\">.</span>dahl_objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\nBook<span class=\"o\">.</span>dahl_objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>title<span class=\"o\">=</span><span class=\"s1\">&#39;Matilda&#39;</span><span class=\"p\">)</span>\nBook<span class=\"o\">.</span>dahl_objects<span class=\"o\">.</span>count<span class=\"p\">()</span>\n</code></pre></div>\n<p>本例同时介绍了另一个有趣的技巧：在一个模型中使用多个管理器。你可以为一个模型添加任意多个 <code class=\"docutils literal notranslate\">Manager()</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=\"nc\">AuthorManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Manager<span class=\"p\">):</span>\n    <span class=\"k\">def</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>get_queryset<span class=\"p\">()</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>role<span class=\"o\">=</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">EditorManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Manager<span class=\"p\">):</span>\n    <span class=\"k\">def</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>get_queryset<span class=\"p\">()</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>role<span class=\"o\">=</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Person</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    first_name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    last_name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    role <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> choices<span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">,</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=\"p\">(</span><span class=\"s1\">&#39;Editor&#39;</span><span class=\"p\">))])</span>\n    people <span class=\"o\">=</span> models<span class=\"o\">.</span>Manager<span class=\"p\">()</span>\n    authors <span class=\"o\">=</span> AuthorManager<span class=\"p\">()</span>\n    editors <span class=\"o\">=</span> EditorManager<span class=\"p\">()</span>\n</code></pre></div>\n<p>本例允许你调用 <code class=\"docutils literal notranslate\">Person.authors.all()</code>， <code class=\"docutils literal notranslate\">Person.editors.all()</code> 和 <code class=\"docutils literal notranslate\">Person.people.all()</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\">Model.</span><span class=\"sig-name descname\">_default_manager</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\">Manager</code> 对象，注意 Django 遇到的第一个 <code class=\"docutils literal notranslate\">Manager</code> （按照你在模型中定义的顺序）会拥有一个独特的状态。Django 将类定义中的第一个 <code class=\"docutils literal notranslate\">Manager</code> 视作 “默认” <code class=\"docutils literal notranslate\">Manager</code>，Django 的几个组件（包括 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\">dumpdata</code></a>）在用到该模型时会独立地调用该 <code class=\"docutils literal notranslate\">Manager</code>。故此，选择默认管理器时要万分小心，避免遇到重写的 <code class=\"docutils literal notranslate\">get_queryset()</code> 无法获取期望的结果这种情况。</p>\n<p>你可以通过 <a class=\"reference internal\" href=\"/zh-hans/2.2/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\">Meta.default_manager_name</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\">_base_manager</code></a>），而不是假定该模型有一个名为 <code class=\"docutils literal notranslate\">objects</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\">Model.</span><span class=\"sig-name descname\">_base_manager</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\">choice.question</code>）时使用 <code class=\"docutils literal notranslate\">Model._base_manager</code> 管理器类的实例，而不是关联对象的 <code class=\"docutils literal notranslate\">_default_manager</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\">django.db.models.Manager</code></a>) 无法满足需求，你可以通过设置 <a class=\"reference internal\" href=\"/zh-hans/2.2/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\">Meta.base_manager_name</code></a> 告诉 Django 使用哪个类。</p>\n<p>在关联模型上执行查询时不会使用基础管理器。例如，若 <a class=\"reference internal\" href=\"/zh-hans/2.2/intro/tutorial02/#creating-models\"><span class=\"std std-ref\">来自教程</span></a> 的模型 <code class=\"docutils literal notranslate\">Question</code> 有个 <code class=\"docutils literal notranslate\">deleted</code> 字段，还有一个基础管理器，用于筛选出 <code class=\"docutils literal notranslate\">deleted=True</code> 的实例。由 <code class=\"docutils literal notranslate\">Choice.objects.filter(question__name__startswith='What')</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\">get_queryset()</code> 方法，并筛掉了全部行，Django 会返回错误的结果。所以，不要这么做。会筛选 <code class=\"docutils literal notranslate\">get_queryset()</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\">QuerySet</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\">QuerySet</code> 方法能直接从 <code class=\"docutils literal notranslate\">Manager</code> 访问，这个实例仅适用于你在自定义 <code class=\"docutils literal notranslate\">QuerySet</code> 中定义了额外方法，且在 <code class=\"docutils literal notranslate\">Manager</code> 中实现了它们:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">PersonQuerySet</span><span class=\"p\">(</span>models<span class=\"o\">.</span>QuerySet<span class=\"p\">):</span>\n    <span class=\"k\">def</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>filter<span class=\"p\">(</span>role<span class=\"o\">=</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</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>filter<span class=\"p\">(</span>role<span class=\"o\">=</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">PersonManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Manager<span class=\"p\">):</span>\n    <span class=\"k\">def</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> PersonQuerySet<span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span>model<span class=\"p\">,</span> using<span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span>_db<span class=\"p\">)</span>\n\n    <span class=\"k\">def</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>get_queryset<span class=\"p\">()</span><span class=\"o\">.</span>authors<span class=\"p\">()</span>\n\n    <span class=\"k\">def</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>get_queryset<span class=\"p\">()</span><span class=\"o\">.</span>editors<span class=\"p\">()</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Person</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    first_name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    last_name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    role <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> choices<span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">,</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=\"p\">(</span><span class=\"s1\">&#39;Editor&#39;</span><span class=\"p\">))])</span>\n    people <span class=\"o\">=</span> PersonManager<span class=\"p\">()</span>\n</code></pre></div>\n<p>本例允许你从管理器 <code class=\"docutils literal notranslate\">Person.people</code> 直接调用 <code class=\"docutils literal notranslate\">authors()</code> 和 <code class=\"docutils literal notranslate\">editors()</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\">QuerySet</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\">QuerySet</code> 和 <code class=\"docutils literal notranslate\">Manager</code>  方法的方案， 可以用 <a class=\"reference internal\" href=\"/zh-hans/2.2/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\">QuerySet.as_manager()</code></a> 创建一个 <code class=\"docutils literal notranslate\">Manager</code> 实例，拷贝了自定义 <code class=\"docutils literal notranslate\">QuerySet</code> 的方法:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Person</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    people <span class=\"o\">=</span> PersonQuerySet<span class=\"o\">.</span>as_manager<span class=\"p\">()</span>\n</code></pre></div>\n<p>由 <a class=\"reference internal\" href=\"/zh-hans/2.2/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\">QuerySet.as_manager()</code></a> 创建的 <code class=\"docutils literal notranslate\">Manager</code> 实例实质上等价于前面例子中的 <code class=\"docutils literal notranslate\">PersonManager</code>。</p>\n<p>不是每个 <code class=\"docutils literal notranslate\">QuerySet</code> 方法在 <code class=\"docutils literal notranslate\">Manager</code> 层都是有意义的；例如，我们故意阻止 <a class=\"reference internal\" href=\"/zh-hans/2.2/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\">QuerySet.delete()</code></a> 被拷贝进 <code class=\"docutils literal notranslate\">Manager</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\">queryset_only</code> 属性值为 <code class=\"docutils literal notranslate\">False</code> 的方法总是会被复制。</p></li>\n<li><p><code class=\"docutils literal notranslate\">queryset_only</code> 属性值为 <code class=\"docutils literal notranslate\">True</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=\"nc\">CustomQuerySet</span><span class=\"p\">(</span>models<span class=\"o\">.</span>QuerySet<span class=\"p\">):</span>\n    <span class=\"c1\"># Available on both Manager and QuerySet.</span>\n    <span class=\"k\">def</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=\"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=\"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    opted_out_public_method<span class=\"o\">.</span>queryset_only <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=\"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    _opted_in_private_method<span class=\"o\">.</span>queryset_only <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\">from_queryset()</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\">classmethod</span> </em><span class=\"sig-name descname\">from_queryset</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">queryset_class</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\">Manager</code> 和一个自定义 <code class=\"docutils literal notranslate\">QuerySet</code>。你可以通过调用 <code class=\"docutils literal notranslate\">Manager.from_queryset()</code> 达成目的，这将会返回一个自定义基础 <code class=\"docutils literal notranslate\">Manager</code> 的子类，带有一份自定义 <code class=\"docutils literal notranslate\">QuerySet</code> 方法的拷贝:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">BaseManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Manager<span class=\"p\">):</span>\n    <span class=\"k\">def</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=\"nc\">CustomQuerySet</span><span class=\"p\">(</span>models<span class=\"o\">.</span>QuerySet<span class=\"p\">):</span>\n    <span class=\"k\">def</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=\"nc\">MyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    objects <span class=\"o\">=</span> BaseManager<span class=\"o\">.</span>from_queryset<span class=\"p\">(</span>CustomQuerySet<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>CustomManager <span class=\"o\">=</span> BaseManager<span class=\"o\">.</span>from_queryset<span class=\"p\">(</span>CustomQuerySet<span class=\"p\">)</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    objects <span class=\"o\">=</span> CustomManager<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/2.2/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\">objects</code> 管理器。</p></li>\n<li><p>一个类的默认管理器要么由 <a class=\"reference internal\" href=\"/zh-hans/2.2/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\">Meta.default_manager_name</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=\"nc\">AbstractBase</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    objects <span class=\"o\">=</span> CustomManager<span class=\"p\">()</span>\n\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        abstract <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>如果您在子类中直接使用这一点，如果您在基类中没有声明任何管理器，那么 <code class=\"docutils literal notranslate\">objects</code> 将是默认的管理器：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">ChildA</span><span class=\"p\">(</span>AbstractBase<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\">AbstractBase</code>，但提供不同的默认管理器，则可以在子类上提供该默认管理器:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">ChildB</span><span class=\"p\">(</span>AbstractBase<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"c1\"># An explicit default manager.</span>\n    default_manager <span class=\"o\">=</span> OtherManager<span class=\"p\">()</span>\n</code></pre></div>\n<p>这里的 <code class=\"docutils literal notranslate\">default_manager</code> 是默认的。继承的 <code class=\"docutils literal notranslate\">objects</code> 管理器仍然可用，只是没有被当做默认管理器。</p>\n<p>最后，对于这个示例，假设您想要向子类中添加额外的管理器，但是仍然使用来自 <code class=\"docutils literal notranslate\">AbstractBase</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=\"nc\">ExtraManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    extra_manager <span class=\"o\">=</span> OtherManager<span class=\"p\">()</span>\n\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        abstract <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">ChildC</span><span class=\"p\">(</span>AbstractBase<span class=\"p\">,</span> ExtraManager<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>ClassA<span class=\"o\">.</span>objects<span class=\"o\">.</span>do_something<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>AbstractBase<span class=\"o\">.</span>objects<span class=\"o\">.</span>do_something<span class=\"p\">()</span>\n</code></pre></div>\n<p>会引发一个异常。这是因为管理器意在封装管理映射对象集合的逻辑。因为您不能拥有抽象对象的集合，所以管理抽象对象是没有意义的。如果您有适用于抽象模型的功能，则应该将该功能放在抽象模型的 <code class=\"docutils literal notranslate\">静态方法</code> 或 <code class=\"docutils literal notranslate\">类方法</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\">Manager</code> 中添加了什么特性，都必须能够对 <code class=\"docutils literal notranslate\">Manager</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=\"nn\">copy</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>manager <span class=\"o\">=</span> MyManager<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>my_copy <span class=\"o\">=</span> copy<span class=\"o\">.</span>copy<span class=\"p\">(</span>manager<span class=\"p\">)</span>\n</code></pre></div>\n<p>Django 在某些查询期间对管理器对象进行浅拷贝；如果您的管理器无法被复制，那么这些查询将失败。</p>\n<p>对于大多数的资源管理器来说，这不是问题。若你只是为 <code class=\"docutils literal notranslate\">Manager</code> 添加简单的方法，一般不会疏忽地把 <code class=\"docutils literal notranslate\">Manager</code> 变的不可拷贝。但是，若重写了 <code class=\"docutils literal notranslate\">Manager</code> 对象用于控制对象状态的 <code class=\"docutils literal notranslate\">__getattr__</code> 或其它私有方法，你需要确认你的修改不会影响 <code class=\"docutils literal notranslate\">Manager</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/2.2/topics/"},{"docname":"topics/db/index","title":"模型和数据库","url":"/zh-hans/2.2/topics/db/"}],"prev":{"docname":"topics/db/search","title":"搜索","url":"/zh-hans/2.2/topics/db/search/"},"next":{"docname":"topics/db/sql","title":"执行原生 SQL 查询","url":"/zh-hans/2.2/topics/db/sql/"},"formats":{"html":"/zh-hans/2.2/topics/db/managers/","markdown":"/zh-hans/2.2/topics/db/managers.md","json":"/zh-hans/2.2/topics/db/managers.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/topics/db/managers.txt","official":"https://docs.djangoproject.com/zh-hans/2.2/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"]}