{"title":"Gestionnaires","version":"1.9","locale":"fr","docname":"topics/db/managers","url":"/fr/1.9/topics/db/managers/","canonical":"https://djangodocs.dev/fr/1.9/topics/db/managers/","summary":"class Manager Lien vers cette définition # Un gestionnaire (objet Manager ) est l’interface par laquelle les opérations de requêtes de base de données sont mises à…","html":"<h1>Gestionnaires<a class=\"heading-anchor\" href=\"#managers\"><span class=\"visually-hidden\">Lien vers cette rubrique</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un gestionnaire (objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>) est l’interface par laquelle les opérations de requêtes de base de données sont mises à disposition des modèles Django. Il existe au moins un <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> pour chaque modèle d’une application Django.</p>\n<p>Le fonctionnement des classes <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> est documenté dans <a class=\"reference internal\" href=\"/fr/1.9/topics/db/queries/\"><span class=\"doc\">Création de requêtes</span></a>; ce document aborde spécifiquement les options de modèles qui personnalisent le comportement des gestionnaires.</p>\n<section id=\"manager-names\">\n<span id=\"id1\"></span><h2>Noms des gestionnaires<a class=\"heading-anchor\" href=\"#manager-names\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Par défaut, Django ajoute un gestionnaire nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> à chaque classe de modèle Django. Cependant, si vous aimeriez utiliser <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> comme nom de champ ou que vous aimeriez nommer le gestionnaire autrement que <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code>, vous pouvez le renommer au niveau du modèle. Pour renommer le gestionnaire d’une classe donnée, définissez un attribut de classe de type <code class=\"docutils literal notranslate\"><span class=\"pre\">models.Manager()</span></code> dans le modèle. Par exemple :</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>En utilisant cet exemple de modèle, <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.objects</span></code> générera une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">AttributeError</span></code>, mais <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.people.all()</span></code> fournira effectivement la liste de tous les objets <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>Gestionnaires personnalisés<a class=\"heading-anchor\" href=\"#custom-managers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Vous pouvez utiliser un gestionnaire personnalisé dans un modèle particulier en étendant la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> de base et en créant votre propre instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> dans votre modèle.</p>\n<p>Il y a deux raisons de vouloir personnaliser un gestionnaire : pour lui ajouter des méthodes supplémentaires ou pour modifier l’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> initial que le gestionnaire renvoie.</p>\n<section id=\"adding-extra-manager-methods\">\n<h3>Ajout de méthodes de gestionnaire supplémentaires<a class=\"heading-anchor\" href=\"#adding-extra-manager-methods\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’ajout de méthodes de gestionnaire supplémentaires est la façon privilégiée d’ajouter des fonctionnalités au « niveau table » à des modèles (pour les fonctionnalités au « niveau ligne », c’est-à-dire les fonctions qui agissent sur une seule instance d’un objet de modèle, utilisez les <a class=\"reference internal\" href=\"/fr/1.9/topics/db/models/#model-methods\"><span class=\"std std-ref\">méthodes de modèles</span></a> et non pas des méthodes de gestionnaire personnalisées).</p>\n<p>Une méthode de gestionnaire personnalisée peut renvoyer tout ce qu’on veut, elle n’est pas tenue de renvoyer un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>.</p>\n<p>Par exemple, cette méthode de gestionnaire personnalisée offre une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">with_counts()</span></code> qui renvoie une liste de tous les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">OpinionPoll</span></code>, chacun recevant un attribut supplémentaire <code class=\"docutils literal notranslate\"><span class=\"pre\">num_responses</span></code> qui est le résultat d’une requête d’agrégation :</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=\"n\">cursor</span> <span class=\"o\">=</span> <span class=\"n\">connection</span><span class=\"o\">.</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>Avec cet exemple, vous écririez <code class=\"docutils literal notranslate\"><span class=\"pre\">OpinionPoll.objects.with_counts()</span></code> pour obtenir la liste des objets <code class=\"docutils literal notranslate\"><span class=\"pre\">OpinionPoll</span></code> comportant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">num_responses</span></code>.</p>\n<p>Une autre chose à relever au sujet de cet exemple est que les méthodes de gestionnaire ont accès à <code class=\"docutils literal notranslate\"><span class=\"pre\">self.model</span></code> pour obtenir la classe de modèle à laquelle elles sont liées.</p>\n</section>\n<section id=\"modifying-a-manager-s-initial-queryset\">\n<h3>Modification des <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> initiaux des gestionnaires<a class=\"heading-anchor\" href=\"#modifying-a-manager-s-initial-queryset\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Le <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> de base d’un gestionnaire renvoie tous les objets du système. Par exemple, en utilisant ce modèle :</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>…l’instruction <code class=\"docutils literal notranslate\"><span class=\"pre\">Book.objects.all()</span></code> renvoie tous les livres de la base de données.</p>\n<p>Vous pouvez surcharger le <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> de base d’un gestionnaire en surchargeant la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager.get_queryset()</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> doit renvoyer un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> doté des propriétés nécessaires.</p>\n<p>Par exemple, le modèle suivant possède <em>deux</em> gestionnaires, un qui renvoie tous les objets et un autre qui ne renvoie que les livres de 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=\"n\">DahlBookManager</span><span class=\"p\">,</span> <span class=\"bp\">self</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>Avec cet exemple de modèle, <code class=\"docutils literal notranslate\"><span class=\"pre\">Book.objects.all()</span></code> renvoie tous les livres de la base de données, mais <code class=\"docutils literal notranslate\"><span class=\"pre\">Book.dahl_objects.all()</span></code> ne retourne que ceux qui ont été écrits par Roald Dahl.</p>\n<p>Naturellement, comme <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>, vous pouvez appliquer <code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude()</span></code> et toutes les autres méthodes de <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>. Ainsi, ces instructions sont toutes valables :</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>Cet exemple a aussi mis en évidence une autre technique intéressante : l’emploi de plusieurs gestionnaires dans un même modèle. Vous pouvez lier autant d’instances de gestionnaires que vous voulez à un modèle. C’est une manière simple de définir des « filtres » fréquemment utilisés dans des modèles.</p>\n<p>Par exemple :</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=\"n\">AuthorManager</span><span class=\"p\">,</span> <span class=\"bp\">self</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=\"n\">EditorManager</span><span class=\"p\">,</span> <span class=\"bp\">self</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>Cet exemple permet d’effectuer les requêtes <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> et <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.people.all()</span></code> en sachant à quoi vous attendre au niveau des résultats.</p>\n<section id=\"default-managers\">\n<span id=\"id3\"></span><h4>Gestionnaires par défaut<a class=\"heading-anchor\" href=\"#default-managers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si vous utilisez des objets <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> personnalisés, sachez que le premier <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> que Django rencontre (dans l’ordre où ils ont été définis dans le modèle) reçoit un statut spécial. Django interprète le premier gestionnaire défini dans une classe comme le gestionnaire par défaut, et plusieurs parties de Django (y compris <a class=\"reference internal\" href=\"/fr/1.9/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">dumpdata</span></code></a>) utilisent exclusivement ce gestionnaire pour le modèle en question. En conséquence, il est conseillé de choisir avec prudence le gestionnaire par défaut afin d’éviter une situation où la surcharge de <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> aboutit à l’incapacité de récupérer des objets avec lesquels vous avez besoin de travailler.</p>\n</section>\n<section id=\"using-managers-for-related-object-access\">\n<span id=\"managers-for-related-objects\"></span><h4>Utilisation de gestionnaires pour accéder aux objets liés<a class=\"heading-anchor\" href=\"#using-managers-for-related-object-access\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Par défaut, Django utilise une instance de classe de gestionnaire « normale » pour accéder aux objets liés (par ex. <code class=\"docutils literal notranslate\"><span class=\"pre\">choice.poll</span></code>), et non pas le gestionnaire par défaut de l’objet lié. Ceci parce que Django doit absolument être capable de récupérer l’objet lié, même dans les cas où il serait filtré (et donc inaccessible) par son gestionnaire par défaut.</p>\n<p>Si la classe de gestionnaire normale (<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>) ne convient pas dans un cas particulier, vous pouvez forcer Django à utiliser la même classe que le gestionnaire par défaut du modèle et définissant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">use_for_related_fields</span></code> dans la classe du gestionnaire. Vous en trouverez la documentation complète <a class=\"reference internal\" href=\"#manager-types\">ci-dessous</a>.</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>Appel personnalisé de méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> depuis le gestionnaire<a class=\"heading-anchor\" href=\"#calling-custom-queryset-methods-from-the-manager\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Alors que la plupart des méthodes d’un <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> standard sont directement accessibles à partir d’un <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>, ce n’est le cas pour les méthodes supplémentaires définies sur un <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> personnalisé que si vous les implémentez également sur le <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>Cet exemple permet d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">authors()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">editors()</span></code> directement depuis le gestionnaire <code class=\"docutils literal notranslate\"><span class=\"pre\">Person.people</span></code>.</p>\n</section>\n<section id=\"creating-a-manager-with-queryset-methods\">\n<span id=\"create-manager-with-queryset-methods\"></span><h3>Création d’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> avec des méthodes de <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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>En lieu et place de l’approche ci-dessus qui nécessite de dupliquer les méthodes à la fois sur les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>,  <a class=\"reference internal\" href=\"/fr/1.9/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> peut être utilisé pour créer une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> avec une copie des méthodes d’un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> personnalisé :</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>L’instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> créée par <a class=\"reference internal\" href=\"/fr/1.9/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> sera pratiquement identique au <code class=\"docutils literal notranslate\"><span class=\"pre\">PersonManager</span></code> de l’exemple précédent.</p>\n<p>Toutes les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> n’ont pas forcément de sens au niveau <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>; par exemple, nous empêchons volontairement la méthode <a class=\"reference internal\" href=\"/fr/1.9/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> d’être copiée vers la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>.</p>\n<p>Les méthodes sont copiées selon les règles suivantes :</p>\n<ul class=\"simple\">\n<li><p>Les méthodes publiques sont copiées par défaut.</p></li>\n<li><p>Les méthodes privées (commençant par un soulignement) ne sont pas copiées par défaut.</p></li>\n<li><p>Les méthodes avec un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset_only</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> sont toujours copiées.</p></li>\n<li><p>Les méthodes avec un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset_only</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ne sont jamais copiées.</p></li>\n</ul>\n<p>Par exemple :</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\">Lien vers cette rubrique</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Pour une utilisation plus avancée, il peut être souhaitable d’avoir à la fois un <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> personnalisé et un <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> personnalisé. Vous pouvez le faire en appelant <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager.from_queryset()</span></code> qui renvoie une <em>sous-classe</em> du <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> de base avec une copie des méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> personnalisées :</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\">BaseManager</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\">BaseManager</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>Vous pouvez également stocker la classe générée dans une variable :</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\">CustomManager</span> <span class=\"o\">=</span> <span class=\"n\">BaseManager</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\">CustomManager</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>Gestionnaires personnalisés et héritage de modèle<a class=\"heading-anchor\" href=\"#custom-managers-and-model-inheritance\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’héritage de classes et les gestionnaires de modèle ne font pas très bon ménage. Les gestionnaires sont souvent spécifiques aux classes dans lesquelles ils sont définis et leur héritage dans des sous-classes n’est pas forcément toujours une bonne idée. Et comme le premier gestionnaire défini devient le <em>gestionnaire par défaut</em>, il est important de pouvoir contrôler cet ordre de définition. Voici donc comment Django se comporte face aux gestionnaires personnalisés et à <a class=\"reference internal\" href=\"/fr/1.9/topics/db/models/#model-inheritance\"><span class=\"std std-ref\">l’héritage de modèles</span></a>:</p>\n<ol class=\"arabic simple\">\n<li><p>Les gestionnaires définis dans les classes de base non abstraites ne sont <em>pas</em> hérités par les classes enfants. Si vous souhaitez réutiliser un gestionnaire d’une base non abstraite, il faut le redéclarer explicitement dans la classe enfant. Ce type de gestionnaire est généralement très spécifique à la classe dans laquelle il est défini, c’est pourquoi leur héritage pourrait produire des résultats inattendus (particulièrement lorsqu’il s’agit du gestionnaire par défaut). Ils ne sont donc pas transmis à leurs classes enfants.</p></li>\n<li><p>Les gestionnaires des classes de base abstraites sont toujours hérités par les classes enfants, par le moyen Python habituel de l’ordre de résolution de nom (les noms des classes enfants surchargent ceux de leurs parents). Les classes de base abstraites sont conçues pour centraliser les informations et les comportements communs à leurs classes enfants. La définition de gestionnaires communs est un aspect entrant tout à fait dans ces informations communes.</p></li>\n<li><p>Le gestionnaire par défaut d’une classe est soit le premier gestionnaire déclaré dans la classe, s’il y en a un, ou le gestionnaire par défaut de la première classe de base abstraite dans la hiérarchie d’héritage, le cas échéant. Si aucun gestionnaire par défaut n’est explicitement déclaré, c’est le gestionnaire par défaut habituel de Django qui est utilisé.</p></li>\n</ol>\n<p>Ces règles assurent la souplesse nécessaire permettant d’installer un ensemble de gestionnaires personnalisés sur un groupe de modèles via une classe de base abstraite, tout en personnalisant aussi le gestionnaire par défaut. Prenons l’exemple de cette classe de base :</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>Si vous l’utilisez directement dans une sous-classe, <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> sera le gestionnaire par défaut si aucun gestionnaire n’est déclaré dans la classe de base :</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>Si vous voulez hériter de <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractBase</span></code>, mais avec un autre gestionnaire par défaut, vous pouvez définir le gestionnaire par défaut dans la classe enfant :</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>Ici, <code class=\"docutils literal notranslate\"><span class=\"pre\">default_manager</span></code> est le gestionnaire par défaut. Le gestionnaire <code class=\"docutils literal notranslate\"><span class=\"pre\">objects</span></code> est toujours disponible, puisqu’il est hérité. Il n’est juste plus le gestionnaire par défaut.</p>\n<p>Pour terminer avec cet exemple, supposons que vous vouliez ajouter des gestionnaires supplémentaires dans la classe enfant tout en conservant le gestionnaire par défaut de <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractBase</span></code>. Vous ne pouvez pas ajouter directement le nouveau gestionnaire dans la classe enfant, car cela surchargerait le gestionnaire par défaut et vous devriez aussi inclure explicitement tous les gestionnaires de la classe de base abstraite. La solution est de placer les gestionnaires supplémentaires dans une autre classe de base et introduire celle-ci dans la hiérarchie d’héritage <em>après</em> ceux par défaut :</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>Notez que même si vous pouvez <em>définir</em> un gestionnaire personnalisé dans le modèle abstrait, vous ne pouvez <em>appeler</em> aucune de ses méthodes au travers du modèle abstrait. C’est-à-dire :</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>est légal, mais :</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>générera une exception. C’est parce que les gestionnaires sont censés intégrer la logique de gestion d’ensembles d’objets. Comme il n’est pas possible d’avoir un ensemble d’objets abstraits, leur gestion n’a pas de sens. Si vous gérez des fonctionnalités s’appliquant au modèle abstrait, vous devriez les placer dans une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">staticmethod</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">classmethod</span></code> du modèle abstrait.</p>\n</section>\n<section id=\"implementation-concerns\">\n<h3>Détails d’implémentation<a class=\"heading-anchor\" href=\"#implementation-concerns\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Quelles que soient les fonctionnalités ajoutées à un gestionnaire personnalisé, il doit toujours être possible de faire une copie légère (« shallow ») d’une de ses instances ; c’est-à-dire que le code suivant doit fonctionner :</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 effectue des copies légères des objets de gestionnaire durant certaines requêtes ; si votre gestionnaire ne peut pas être copié, ces requêtes échoueront.</p>\n<p>Ce ne sera pas un problème pour la plupart des gestionnaires personnalisés. Si vous ne faites qu’ajouter des méthodes simples à votre classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code>, il est improbable que vous empêchiez la copie de votre gestionnaire sans le vouloir. Cependant, si vous surchargez <code class=\"docutils literal notranslate\"><span class=\"pre\">__getattr__</span></code> ou d’autres méthodes privées de l’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Manager</span></code> qui contrôlent l’état de l’objet, il faut vous assurer que vous n’altériez pas la capacité de votre gestionnaire d’être copié.</p>\n</section>\n</section>\n<section id=\"controlling-automatic-manager-types\">\n<span id=\"manager-types\"></span><h2>Contrôle du type des gestionnaires automatiques<a class=\"heading-anchor\" href=\"#controlling-automatic-manager-types\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ce document a déjà mentionné quelques endroits où Django crée automatiquement une classe de gestionnaire : <a class=\"reference internal\" href=\"#id3\">gestionnaires par défaut</a> et le gestionnaire « de base » utilisé pour <a class=\"reference internal\" href=\"#manager-names\">accéder aux objets liés</a>. Il y a d’autres endroits dans l’implémentation de Django où des gestionnaires de base temporaires sont nécessaires. Ces gestionnaires automatiquement créés sont normalement des instances de la classe <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>.</p>\n<p>Tout au long de cette section, nous utiliserons le terme « gestionnaire automatique » pour désigner les gestionnaires que Django crée pour vous, soit comme un gestionnaire par défaut d’un modèle sans gestionnaire ou pour un usage temporaire lors de l’accès à des objets liés.</p>\n<p>Cette classe par défaut n’est parfois pas le bon choix. Le gestionnaire par défaut peut ne pas disposer de toutes les méthodes nécessaires à la manipulation des données. Une classe de gestionnaire personnalisée selon vos besoins permet de créer des objets <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> personnalisés pour obtenir les informations dont vous avez besoin.</p>\n<p>Django propose aux développeurs de gestionnaires personnalisés une manière d’indiquer que leur classe de gestionnaire doit être utilisée pour les gestionnaires automatiques chaque fois qu’ils deviennent le gestionnaire par défaut d’un modèle. Ceci se fait en définissant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">use_for_related_fields</span></code> dans la classe du gestionnaire :</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\">MyManager</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=\"n\">use_for_related_fields</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n    <span class=\"c1\"># ...</span>\n</code></pre></div>\n<p>Si cet attribut est défini dans le gestionnaire <em>par défaut</em> d’un modèle (seul le gestionnaire par défaut est considéré dans ces situations), Django utilise cette classe chaque fois qu’il a besoin de créer automatiquement un gestionnaire pour la classe. Sinon, il utilise <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>.</p>\n<aside class=\"admonition-historical-note admonition\">\n<p class=\"admonition-title\">Note historique</p>\n<p>Étant donné le but pour lequel il est utilisé, le nom de cet attribut (<code class=\"docutils literal notranslate\"><span class=\"pre\">use_for_related_fields</span></code>) peut sembler un peu bizarre. À l’origine, cet attribut ne contrôlait que le type de gestionnaire utilisé pour l’accès aux champs liés, d’où son nom. Ce nom n’a ensuite pas été modifié, même quand il paraissait de plus en plus clair que le concept était plus largement utile. Ceci principalement pour <a class=\"reference internal\" href=\"/fr/1.9/misc/api-stability/\"><span class=\"doc\">préserver le fonctionnement du code existant</span></a> dans les versions futures de Django.</p>\n</aside>\n<section id=\"writing-correct-managers-for-use-in-automatic-manager-instances\">\n<h3>Écriture correcte de gestionnaires pour les instances automatiques<a class=\"heading-anchor\" href=\"#writing-correct-managers-for-use-in-automatic-manager-instances\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La fonctionnalité <code class=\"docutils literal notranslate\"><span class=\"pre\">use_for_related_fields</span></code> est principalement axée sur les gestionnaires qui ont besoin de renvoyer une sous-classe de <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> personnalisée. Lorsque vous utilisez cette fonctionnalité dans un gestionnaire, il ne fait pas oublier certaines choses.</p>\n<section id=\"do-not-filter-away-any-results-in-this-type-of-manager-subclass\">\n<h4>Ne jamais filtrer les résultats dans ce type de sous-classe de gestionnaire<a class=\"heading-anchor\" href=\"#do-not-filter-away-any-results-in-this-type-of-manager-subclass\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>L’une des raisons pour lesquelles un gestionnaire automatique est utilisé est le besoin d’accéder aux objets liés à partir d’un autre modèle. Dans ces situations, Django doit être capable de voir tous les objets du modèle qu’il récupère, afin que <em>tout</em> ce qui est référencé puisse être récupéré.</p>\n<p>Si vous surchargez la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> et que vous excluez certaines lignes, Django renverra des résultats incorrects. Ne faites pas cela. Un gestionnaire excluant des résultats dans <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> n’est pas approprié comme gestionnaire automatique.</p>\n</section>\n<section id=\"set-use-for-related-fields-when-you-define-the-class\">\n<h4>Définir <code class=\"docutils literal notranslate\"><span class=\"pre\">use_for_related_fields</span></code> lors de la création de la classe<a class=\"heading-anchor\" href=\"#set-use-for-related-fields-when-you-define-the-class\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>L’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">use_for_related_fields</span></code> doit être défini dans la <em>classe</em> du gestionnaire, et non pas dans une <em>instance</em> de la classe. L’exemple précédent montre la bonne manière de le faire, tandis que le code suivant ne fonctionnera pas :</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\"># BAD: Incorrect code</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyManager</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=\"c1\"># ...</span>\n    <span class=\"k\">pass</span>\n\n<span class=\"c1\"># Sets the attribute on an instance of MyManager. Django will</span>\n<span class=\"c1\"># ignore this setting.</span>\n<span class=\"n\">mgr</span> <span class=\"o\">=</span> <span class=\"n\">MyManager</span><span class=\"p\">()</span>\n<span class=\"n\">mgr</span><span class=\"o\">.</span><span class=\"n\">use_for_related_fields</span> <span class=\"o\">=</span> <span class=\"kc\">True</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=\"c1\"># ...</span>\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">mgr</span>\n\n<span class=\"c1\"># End of incorrect code.</span>\n</code></pre></div>\n<p>De plus, vous ne devriez pas modifier l’attribut de l’objet classe après qu’il a été utilisé dans un modèle, car la valeur de l’attribut est prise en compte au moment de la création de la classe de modèle et n’est plus relue plus tard. Définissez l’attribut de la classe de gestionnaire lors de sa définition initiale comme dans le premier exemple de cette section et tout devrait fonctionner à merveille.</p>\n</section>\n</section>\n</section>","rootId":"managers","toc":[{"title":"Noms des gestionnaires","anchor":"manager-names","children":[]},{"title":"Gestionnaires personnalisés","anchor":"custom-managers","children":[{"title":"Ajout de méthodes de gestionnaire supplémentaires","anchor":"adding-extra-manager-methods","children":[]},{"title":"Modification des QuerySet initiaux des gestionnaires","anchor":"modifying-a-manager-s-initial-queryset","children":[{"title":"Gestionnaires par défaut","anchor":"default-managers","children":[]},{"title":"Utilisation de gestionnaires pour accéder aux objets liés","anchor":"using-managers-for-related-object-access","children":[]}]},{"title":"Appel personnalisé de méthodes QuerySet depuis le gestionnaire","anchor":"calling-custom-queryset-methods-from-the-manager","children":[]},{"title":"Création d’objet Manager avec des méthodes de QuerySet","anchor":"creating-a-manager-with-queryset-methods","children":[{"title":"from_queryset()","anchor":"from-queryset","children":[]}]},{"title":"Gestionnaires personnalisés et héritage de modèle","anchor":"custom-managers-and-model-inheritance","children":[]},{"title":"Détails d’implémentation","anchor":"implementation-concerns","children":[]}]},{"title":"Contrôle du type des gestionnaires automatiques","anchor":"controlling-automatic-manager-types","children":[{"title":"Écriture correcte de gestionnaires pour les instances automatiques","anchor":"writing-correct-managers-for-use-in-automatic-manager-instances","children":[{"title":"Ne jamais filtrer les résultats dans ce type de sous-classe de gestionnaire","anchor":"do-not-filter-away-any-results-in-this-type-of-manager-subclass","children":[]},{"title":"Définir use_for_related_fields lors de la création de la classe","anchor":"set-use-for-related-fields-when-you-define-the-class","children":[]}]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/1.9/topics/"},{"docname":"topics/db/index","title":"Modèles et bases de données","url":"/fr/1.9/topics/db/"}],"prev":{"docname":"topics/db/aggregation","title":"Agrégation","url":"/fr/1.9/topics/db/aggregation/"},"next":{"docname":"topics/db/sql","title":"Lancement de requêtes SQL brutes","url":"/fr/1.9/topics/db/sql/"},"formats":{"html":"/fr/1.9/topics/db/managers/","markdown":"/fr/1.9/topics/db/managers.md","json":"/fr/1.9/topics/db/managers.json"},"source":"https://github.com/django/django/blob/stable/1.9.x/docs/topics/db/managers.txt","official":"https://docs.djangoproject.com/fr/1.9/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","1.11","1.10","1.9"],"inLocales":["en","fr","ja","id","pt-br","es"]}