{"title":"Modèles","version":"1.9","locale":"fr","docname":"topics/db/models","url":"/fr/1.9/topics/db/models/","canonical":"https://djangodocs.dev/fr/1.9/topics/db/models/","summary":"Un modèle est la source d’information unique et définitive à propos de vos données. Il contient les champs et le comportement essentiels des données que vous…","html":"<span id=\"models\"></span><h1>Modèles<a class=\"heading-anchor\" href=\"#module-django.db.models\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Un modèle est la source d’information unique et définitive à propos de vos données. Il contient les champs et le comportement essentiels des données que vous stockez. Généralement, chaque modèle correspond à une seule table de base de données.</p>\n<p>Les bases :</p>\n<ul class=\"simple\">\n<li><p>Chaque modèle est une classe Python qui hérite de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model\" title=\"django.db.models.Model\"><code class=\"xref py py-class docutils literal notranslate\">django.db.models.Model</code></a>.</p></li>\n<li><p>Chaque attribut du modèle représente un champ de base de données.</p></li>\n<li><p>Avec tout ça, Django vous offre une API d’accès à la base de données générée automatiquement ; voir <a class=\"reference internal\" href=\"/fr/1.9/topics/db/queries/\"><span class=\"doc\">Création de requêtes</span></a>.</p></li>\n</ul>\n<section id=\"quick-example\">\n<h2>Exemple rapide<a class=\"heading-anchor\" href=\"#quick-example\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Cet exemple de modèle définit une personne (<code class=\"docutils literal notranslate\">Person</code>) avec un prénom (<code class=\"docutils literal notranslate\">first_name</code>) et un nom (<code class=\"docutils literal notranslate\">last_name</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    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\">30</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\">30</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">first_name</code> et <code class=\"docutils literal notranslate\">last_name</code> sont des <a class=\"reference internal\" href=\"#fields\">champs</a> du modèle. Chaque champ est défini comme un attribut de classe, et chaque attribut correspond à une colonne de base de données.</p>\n<p>Le modèle <code class=\"docutils literal notranslate\">Person</code> ci-dessus va créer une table de base de données comme celle-ci :</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">CREATE</span> <span class=\"k\">TABLE</span> myapp_person <span class=\"p\">(</span>\n    <span class=\"ss\">&quot;id&quot;</span> <span class=\"nb\">serial</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span> <span class=\"k\">PRIMARY</span> <span class=\"k\">KEY</span><span class=\"p\">,</span>\n    <span class=\"ss\">&quot;first_name&quot;</span> <span class=\"nb\">varchar</span><span class=\"p\">(</span><span class=\"mi\">30</span><span class=\"p\">)</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span><span class=\"p\">,</span>\n    <span class=\"ss\">&quot;last_name&quot;</span> <span class=\"nb\">varchar</span><span class=\"p\">(</span><span class=\"mi\">30</span><span class=\"p\">)</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span>\n<span class=\"p\">);</span>\n</code></pre></div>\n<p>Quelques notes techniques :</p>\n<ul class=\"simple\">\n<li><p>Le nom de la table, <code class=\"docutils literal notranslate\">myapp_person</code>, est automatiquement dérivé de certaines métadonnées du modèle mais peut être surchargé. Consultez <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#table-names\"><span class=\"std std-ref\">Noms de tables</span></a> pour plus de détails.</p></li>\n<li><p>Un champ <code class=\"docutils literal notranslate\">id</code> est ajouté automatiquement, mais ce comportement peut être adapté. Voir <a class=\"reference internal\" href=\"#automatic-primary-key-fields\"><span class=\"std std-ref\">Champs clé primaire automatiques</span></a>.</p></li>\n<li><p>Le code SQL <code class=\"docutils literal notranslate\">CREATE TABLE</code> de cet exemple est mis en forme avec la syntaxe PostgreSQL, mais il est utile de relever que Django utilise du code SQL adapté au moteur de base de données indiqué dans votre <a class=\"reference internal\" href=\"/fr/1.9/topics/settings/\"><span class=\"doc\">fichier de réglages</span></a>.</p></li>\n</ul>\n</section>\n<section id=\"using-models\">\n<h2>Utilisation des modèles<a class=\"heading-anchor\" href=\"#using-models\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Après avoir défini les modèles, il faut indiquer à Django que vous souhaitez <em>utiliser</em> ces modèles. Vous pouvez le faire en éditant votre fichier de réglages et en modifiant le réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> pour y ajouter le nom du module qui contient <code class=\"docutils literal notranslate\">models.py</code>.</p>\n<p>Par exemple, si le modèle de votre application se trouve dans le module <code class=\"docutils literal notranslate\">myapp.models</code> (la structure de paquet créée pour une application par le script  <a class=\"reference internal\" href=\"/fr/1.9/ref/django-admin/#django-admin-startapp\"><code class=\"xref std std-djadmin docutils literal notranslate\">manage.py startapp</code></a>),  <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> devrait contenir :</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>INSTALLED_APPS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\">#...</span>\n    <span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span>\n    <span class=\"c1\">#...</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Lorsque vous ajoutez de nouvelles applications à <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a>, n’oubliez pas ensuite de lancer <a class=\"reference internal\" href=\"/fr/1.9/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">manage.py migrate</code></a>, en créant éventuellement d’abord des migrations pour ces applications avec <a class=\"reference internal\" href=\"/fr/1.9/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\">manage.py makemigrations</code></a>.</p>\n</section>\n<section id=\"fields\">\n<h2>Champs<a class=\"heading-anchor\" href=\"#fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La partie la plus importante d’un modèle (et la seule qui soit obligatoire) est la liste des champs de base de données qu’il définit. Les champs sont définis par des attributs de classe. Faites attention à ne pas choisir des noms de champs qui entrent en conflit avec l”<a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/\"><span class=\"doc\">API des modèles</span></a> comme <code class=\"docutils literal notranslate\">clean</code>, <code class=\"docutils literal notranslate\">save</code> ou <code class=\"docutils literal notranslate\">delete</code>.</p>\n<p>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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">Musician</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    instrument <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\n<span class=\"k\">class</span> <span class=\"nc\">Album</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    artist <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Musician<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    release_date <span class=\"o\">=</span> models<span class=\"o\">.</span>DateField<span class=\"p\">()</span>\n    num_stars <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span>\n</code></pre></div>\n<section id=\"field-types\">\n<h3>Types de champs<a class=\"heading-anchor\" href=\"#field-types\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Chaque champ de votre modèle doit être une instance de la classe <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> appropriée. Django utilise les types des classes de champs pour déterminer un certain nombre de choses :</p>\n<ul class=\"simple\">\n<li><p>Le type de la colonne, qui indique à la base de données le genre de données à stocker (par ex. <code class=\"docutils literal notranslate\">INTEGER</code>, <code class=\"docutils literal notranslate\">VARCHAR</code>, <code class=\"docutils literal notranslate\">TEXT</code>).</p></li>\n<li><p>Le <a class=\"reference internal\" href=\"/fr/1.9/ref/forms/widgets/\"><span class=\"doc\">composant HTML</span></a> par défaut à utiliser lors de la création d’un champ de formulaire (par ex. : <code class=\"docutils literal notranslate\">&lt;input type=&quot;text&quot;&gt;</code>, <code class=\"docutils literal notranslate\">&lt;select&gt;</code>).</p></li>\n<li><p>Les exigences minimales de validation, utilisées dans l’administration de Django et dans les formulaires générés automatiquement.</p></li>\n</ul>\n<p>Django est fourni avec des dizaines de types de champs intégrés ; vous trouverez la liste complète dans la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#model-field-types\"><span class=\"std std-ref\">référence des champs de modèle</span></a>. Vous pouvez facilement écrire vos propres champs si ceux proposés par Django ne font pas l’affaire ; voir <a class=\"reference internal\" href=\"/fr/1.9/howto/custom-model-fields/\"><span class=\"doc\">Écriture de champs de modèles personnalisés</span></a>.</p>\n</section>\n<section id=\"field-options\">\n<h3>Options des champs<a class=\"heading-anchor\" href=\"#field-options\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Chaque champ accepte un certain nombre de paramètres spécifiques (documentés dans la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#model-field-types\"><span class=\"std std-ref\">référence des champs de modèle</span></a>). Par exemple, <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.CharField\" title=\"django.db.models.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a> (et ses sous-classes) exige un paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.CharField.max_length\" title=\"django.db.models.CharField.max_length\"><code class=\"xref py py-attr docutils literal notranslate\">max_length</code></a> indiquant la taille du champ de base de données <code class=\"docutils literal notranslate\">VARCHAR</code> qui stockera les données.</p>\n<p>Il existe aussi un ensemble de paramètres communs à tous les types de champs. Ils sont tous facultatifs. Ils sont décrits en détails dans la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#common-model-field-options\"><span class=\"std std-ref\">référence</span></a>, mais voici un résumé rapide de ceux qui sont le plus souvent utilisés :</p>\n<dl>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.null\" title=\"django.db.models.Field.null\"><code class=\"xref py py-attr docutils literal notranslate\">null</code></a></dt><dd><p>Si la valeur est <code class=\"docutils literal notranslate\">True</code>, Django stocke les valeurs vides avec  <code class=\"docutils literal notranslate\">NULL</code> dans la base de données. La valeur par défaut est <code class=\"docutils literal notranslate\">False</code>.</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.blank\" title=\"django.db.models.Field.blank\"><code class=\"xref py py-attr docutils literal notranslate\">blank</code></a></dt><dd><p>Si la valeur est <code class=\"docutils literal notranslate\">True</code>, le champ peut être vide. La valeur par défaut est <code class=\"docutils literal notranslate\">False</code>.</p>\n<p>Notez que ce n’est pas la même chose que <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.null\" title=\"django.db.models.Field.null\"><code class=\"xref py py-attr docutils literal notranslate\">null</code></a>. <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.null\" title=\"django.db.models.Field.null\"><code class=\"xref py py-attr docutils literal notranslate\">null</code></a> est purement lié à la base de données alors que <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.blank\" title=\"django.db.models.Field.blank\"><code class=\"xref py py-attr docutils literal notranslate\">blank</code></a> est lié à la validation. Si un champ possède <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.blank\" title=\"django.db.models.Field.blank\"><code class=\"xref py py-attr docutils literal notranslate\">blank=True</code></a>, la validation de formulaire permet la saisie d’une valeur vide. Si un champ possède <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.blank\" title=\"django.db.models.Field.blank\"><code class=\"xref py py-attr docutils literal notranslate\">blank=False</code></a>, le champ est obligatoire.</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.choices\" title=\"django.db.models.Field.choices\"><code class=\"xref py py-attr docutils literal notranslate\">choices</code></a></dt><dd><p>Un itérable (une liste ou un tuple) de tuples à 2 valeurs à utiliser comme liste de choix pour ce champ. Quand ce paramètre est présent, le composant de formulaire par défaut est une liste déroulante au lieu du champ de texte standard et seules les valeurs proposées dans la liste seront acceptées.</p>\n<p>Une liste de choix ressemble à ceci :</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>YEAR_IN_SCHOOL_CHOICES <span class=\"o\">=</span> <span class=\"p\">(</span>\n    <span class=\"p\">(</span><span class=\"s1\">&#39;FR&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Freshman&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">(</span><span class=\"s1\">&#39;SO&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Sophomore&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">(</span><span class=\"s1\">&#39;JR&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Junior&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">(</span><span class=\"s1\">&#39;SR&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Senior&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">(</span><span class=\"s1\">&#39;GR&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Graduate&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>Le premier élément de chaque tuple est la valeur qui sera stockée dans la base de données. Le second élément est celui qui est affiché dans le composant de formulaire par défaut ou dans un <a class=\"reference internal\" href=\"/fr/1.9/ref/forms/fields/#django.forms.ModelChoiceField\" title=\"django.forms.ModelChoiceField\"><code class=\"xref py py-class docutils literal notranslate\">ModelChoiceField</code></a>. Étant donné une instance de modèle, la valeur d’affichage d’un champ comportant des choix peut être accédée en utilisant la méthode <code class=\"docutils literal notranslate\">get_FOO_display()</code>. 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=\"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    SHIRT_SIZES <span class=\"o\">=</span> <span class=\"p\">(</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;S&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Small&#39;</span><span class=\"p\">),</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;M&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Medium&#39;</span><span class=\"p\">),</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;L&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Large&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">)</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">60</span><span class=\"p\">)</span>\n    shirt_size <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>SHIRT_SIZES<span class=\"p\">)</span>\n</code></pre></div>\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>p <span class=\"o\">=</span> Person<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Fred Flintstone&quot;</span><span class=\"p\">,</span> shirt_size<span class=\"o\">=</span><span class=\"s2\">&quot;L&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p<span class=\"o\">.</span>save<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p<span class=\"o\">.</span>shirt_size\n<span class=\"go\">&#39;L&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p<span class=\"o\">.</span>get_shirt_size_display<span class=\"p\">()</span>\n<span class=\"go\">&#39;Large&#39;</span>\n</code></pre></div>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.default\" title=\"django.db.models.Field.default\"><code class=\"xref py py-attr docutils literal notranslate\">default</code></a></dt><dd><p>La valeur par défaut du champ. Cela peut être une valeur ou un objet exécutable. Dans ce dernier cas, l’objet est appelé lors de chaque création d’un nouvel objet.</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.help_text\" title=\"django.db.models.Field.help_text\"><code class=\"xref py py-attr docutils literal notranslate\">help_text</code></a></dt><dd><p>Texte d’aide supplémentaire à afficher avec le composant de formulaire. Utile pour la documentation même si le champ n’est pas utilisé dans un formulaire.</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">primary_key</code></a></dt><dd><p>Si la valeur est <code class=\"docutils literal notranslate\">True</code>, ce champ représentera la clé primaire du modèle.</p>\n<p>Si vous n’indiquez aucun paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">primary_key=True</code></a> dans les champs d’un modèle, Django ajoute automatiquement un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.IntegerField\" title=\"django.db.models.IntegerField\"><code class=\"xref py py-class docutils literal notranslate\">IntegerField</code></a> pour constituer une clé primaire ; il n’est donc pas nécessaire de définir le paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">primary_key=True</code></a> pour un champ sauf si vous souhaitez modifier le comportement par défaut de clé primaire automatique. Pour en savoir plus, consultez <a class=\"reference internal\" href=\"#automatic-primary-key-fields\"><span class=\"std std-ref\">Champs clé primaire automatiques</span></a>.</p>\n<p>Le champ de clé primaire est en lecture seule. Si vous modifiez la valeur de la clé primaire d’un objet existant et que vous l’enregistrez, un nouvel objet est créé en parallèle à l’ancien. 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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">Fruit</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>fruit <span class=\"o\">=</span> Fruit<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s1\">&#39;Apple&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>fruit<span class=\"o\">.</span>name <span class=\"o\">=</span> <span class=\"s1\">&#39;Pear&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>fruit<span class=\"o\">.</span>save<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Fruit<span class=\"o\">.</span>objects<span class=\"o\">.</span>values_list<span class=\"p\">(</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">,</span> flat<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"go\">[&#39;Apple&#39;, &#39;Pear&#39;]</span>\n</code></pre></div>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.unique\" title=\"django.db.models.Field.unique\"><code class=\"xref py py-attr docutils literal notranslate\">unique</code></a></dt><dd><p>Si la valeur est <code class=\"docutils literal notranslate\">True</code>, ce champ doit être unique dans toute la table.</p>\n</dd>\n</dl>\n<p>Répétons encore une fois que ce n’était que de courtes descriptions des options de champs les plus courantes. Des détails complets peuvent être obtenus dans la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#common-model-field-options\"><span class=\"std std-ref\">référence des options communes des champs de modèle</span></a>.</p>\n</section>\n<section id=\"automatic-primary-key-fields\">\n<span id=\"id1\"></span><h3>Champs clé primaire automatiques<a class=\"heading-anchor\" href=\"#automatic-primary-key-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Par défaut, Django ajoute à chaque modèle le champ suivant :</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=\"nb\">id</span> <span class=\"o\">=</span> models<span class=\"o\">.</span>AutoField<span class=\"p\">(</span>primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>C’est une clé primaire avec incrémentation automatique.</p>\n<p>Si vous souhaitez spécifier une clé primaire personnalisée, il suffit d’ajouter <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">primary_key=True</code></a> à l’un de vos champs. Si Django voit que vous avez explicitement défini  <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">Field.primary_key</code></a>, il n’ajoutera pas de colonne <code class=\"docutils literal notranslate\">id</code> automatique.</p>\n<p>Pour chaque modèle, il est obligatoire d’avoir un et un seul champ ayant le paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">primary_key=True</code></a> (qu’il soit déclaré explicitement ou ajouté automatiquement).</p>\n</section>\n<section id=\"verbose-field-names\">\n<span id=\"id2\"></span><h3>Noms de champs verbeux<a class=\"heading-anchor\" href=\"#verbose-field-names\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Chaque type de champ, à l’exception de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a>, <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> et <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a>, accepte un premier paramètre positionnel facultatif, un nom verbeux. Si le nom verbeux n’est pas défini, Django le crée automatiquement en se basant sur le nom d’attribut du champ, remplaçant les soulignements par des espaces.</p>\n<p>Dans cet exemple, le nom verbeux est <code class=\"docutils literal notranslate\">&quot;person's first name&quot;</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>first_name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span><span class=\"s2\">&quot;person&#39;s first name&quot;</span><span class=\"p\">,</span> max_length<span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Dans cet exemple, le nom verbeux est <code class=\"docutils literal notranslate\">&quot;first name&quot;</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>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\">30</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a>, <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> et <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> exigent que le premier paramètre soit une classe de modèle, il est donc nécessaire d’utiliser le paramètre nommé <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.verbose_name\" title=\"django.db.models.Field.verbose_name\"><code class=\"xref py py-attr docutils literal notranslate\">verbose_name</code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>poll <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>\n    Poll<span class=\"p\">,</span>\n    on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">,</span>\n    verbose_name<span class=\"o\">=</span><span class=\"s2\">&quot;the related poll&quot;</span><span class=\"p\">,</span>\n<span class=\"p\">)</span>\nsites <span class=\"o\">=</span> models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span>Site<span class=\"p\">,</span> verbose_name<span class=\"o\">=</span><span class=\"s2\">&quot;list of sites&quot;</span><span class=\"p\">)</span>\nplace <span class=\"o\">=</span> models<span class=\"o\">.</span>OneToOneField<span class=\"p\">(</span>\n    Place<span class=\"p\">,</span>\n    on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">,</span>\n    verbose_name<span class=\"o\">=</span><span class=\"s2\">&quot;related place&quot;</span><span class=\"p\">,</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>La convention est de ne pas mettre en majuscule la première lettre de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.verbose_name\" title=\"django.db.models.Field.verbose_name\"><code class=\"xref py py-attr docutils literal notranslate\">verbose_name</code></a>. Django le fera automatiquement là où il pense que c’est nécessaire.</p>\n</section>\n<section id=\"relationships\">\n<h3>Relations<a class=\"heading-anchor\" href=\"#relationships\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Clairement, la puissance des base de données relationnelles se trouve dans les liaisons entre tables. Django propose des méthodes pour définir les trois types de relations les plus courantes : plusieurs-à-un, plusieurs-à-plusieurs et un-à-un.</p>\n<section id=\"many-to-one-relationships\">\n<h4>Relations plusieurs-à-un<a class=\"heading-anchor\" href=\"#many-to-one-relationships\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Pour définir une relation plusieurs-à-un, utilisez <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">django.db.models.ForeignKey</code></a>. Son utilisation est pareille à celle des autres types de champs <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> : il s’agit d’un attribut de classe d’un modèle.</p>\n<p><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> exige un paramètre positionnel : la classe à laquelle le modèle est lié.</p>\n<p>Par exemple, si un modèle <code class=\"docutils literal notranslate\">Car</code> (voiture) possède un <code class=\"docutils literal notranslate\">Manufacturer</code> (fabriquant), c’est-à-dire qu’un <code class=\"docutils literal notranslate\">Manufacturer</code> peut produire plusieurs voitures mais chaque <code class=\"docutils literal notranslate\">Car</code> n’a qu’un seul <code class=\"docutils literal notranslate\">Manufacturer</code>, voici le code correspondant :</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\">Manufacturer</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">pass</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Car</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    manufacturer <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Manufacturer<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    <span class=\"c1\"># ...</span>\n</code></pre></div>\n<p>Il est aussi possible de créer des <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#recursive-relationships\"><span class=\"std std-ref\">relations récursives</span></a> (un objet avec une relation plusieurs-à-un avec lui-même) et des <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#lazy-relationships\"><span class=\"std std-ref\">relations vers des modèles non encore définis</span></a> ; consultez la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#ref-foreignkey\"><span class=\"std std-ref\">référence des champs de modèle</span></a> pour plus de détails.</p>\n<p>Il est recommandé mais non obligatoire que le nom d’un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> (<code class=\"docutils literal notranslate\">manufacturer</code> dans l’exemple ci-dessus) soit égal au nom du modèle en minuscules. Vous pouvez évidemment nommer le champ de la manière qui vous convient. 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=\"nc\">Car</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    company_that_makes_it <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>\n        Manufacturer<span class=\"p\">,</span>\n        on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">,</span>\n    <span class=\"p\">)</span>\n    <span class=\"c1\"># ...</span>\n</code></pre></div>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">Voir aussi</p>\n<p>Les champs <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> acceptent quelques paramètres supplémentaires qui sont présentés dans la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#foreign-key-arguments\"><span class=\"std std-ref\">référence des champs de modèle</span></a>. Ces options aident à spécifier le fonctionnement de la relation ; toutes sont facultatives.</p>\n<p>Pour plus de détails sur l’accès aux objets par référence liée inverse, consultez l”<a class=\"reference internal\" href=\"/fr/1.9/topics/db/queries/#backwards-related-objects\"><span class=\"std std-ref\">exemple de l’accès aux relations inverses</span></a>.</p>\n<p>Pour des exemples de code, consultez les <a class=\"reference internal\" href=\"/fr/1.9/topics/db/examples/many_to_one/\"><span class=\"doc\">exemples de relations plusieurs-à-un entre modèles</span></a>.</p>\n</aside>\n</section>\n<section id=\"many-to-many-relationships\">\n<h4>Relations plusieurs-à-plusieurs<a class=\"heading-anchor\" href=\"#many-to-many-relationships\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Pour définir une relation plusieurs-à-plusieurs, utilisez <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">django.db.models.ManyToManyField</code></a>. Son utilisation est pareille à celle des autres types de champs <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> : il s’agit d’un attribut de classe d’un modèle.</p>\n<p><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> exige un paramètre positionnel : la classe à laquelle le modèle est lié.</p>\n<p>Par exemple, si une <code class=\"docutils literal notranslate\">Pizza</code> possède plusieurs objets <code class=\"docutils literal notranslate\">Topping</code> (garniture), c’est-à-dire qu’un <code class=\"docutils literal notranslate\">Topping</code> peut se trouver sur plusieurs pizzas et chaque <code class=\"docutils literal notranslate\">Pizza</code> possède plusieurs garnitures, voici comment ce cas de figure serait représenté :</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\">Topping</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">pass</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Pizza</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    toppings <span class=\"o\">=</span> models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span>Topping<span class=\"p\">)</span>\n</code></pre></div>\n<p>Comme pour <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a>, il est aussi possible de créer des <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#recursive-relationships\"><span class=\"std std-ref\">relations récursives</span></a> (un objet avec une relation plusieurs-à-plusieurs avec lui-même) et des <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#lazy-relationships\"><span class=\"std std-ref\">relations vers des modèles non encore définis</span></a>.</p>\n<p>Il est recommandé mais non obligatoire que le nom d’un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> (<code class=\"docutils literal notranslate\">toppings</code> dans l’exemple ci-dessus) soit un pluriel décrivant l’ensemble des objets modèles liés.</p>\n<p>Que le champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> soit placé sur un modèle ou l’autre ne change pas grand chose, mais il est essentiel de ne le mettre que dans un des modèles, pas dans les deux.</p>\n<p>Généralement, les instances <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> devraient être placées dans l’objet qui va être modifié par un formulaire. Dans l’exemple ci-dessus, les toppings` sont dans <code class=\"docutils literal notranslate\">Pizza</code> (plutôt que ce soit <code class=\"docutils literal notranslate\">Topping</code> qui possède un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> de <code class=\"docutils literal notranslate\">pizzas</code> ) parce qu’il est plus logique d’imaginer une pizza ayant plusieurs garnitures qu’une garniture se trouvant dans plusieurs pizzas. De la manière dont les choses ont été définies ci-dessus, le formulaire <code class=\"docutils literal notranslate\">Pizza</code> permettra de choisir des garnitures.</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">Voir aussi</p>\n<p>Consultez les <a class=\"reference internal\" href=\"/fr/1.9/topics/db/examples/many_to_many/\"><span class=\"doc\">exemples de relations plusieurs-à-plusieurs entre modèles</span></a> pour voir un exemple complet.</p>\n</aside>\n<p>Les champs <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> acceptent aussi quelques paramètres supplémentaires qui sont présentés dans la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#manytomany-arguments\"><span class=\"std std-ref\">référence des champs de modèle</span></a>. Ces options aident à spécifier le fonctionnement de la relation ; toutes sont facultatives.</p>\n</section>\n<section id=\"extra-fields-on-many-to-many-relationships\">\n<span id=\"intermediary-manytomany\"></span><h4>Champs supplémentaires dans les relations plusieurs-à-plusieurs<a class=\"heading-anchor\" href=\"#extra-fields-on-many-to-many-relationships\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Lorsque vous devez gérer des relations plusieurs-à-plusieurs simples comme le mélange et la combinaison de pizzas et de garnitures, un <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> standard suffit. Cependant, il est parfois nécessaire d’associer des données à la relation entre deux modèles.</p>\n<p>Par exemple, considérez le cas d’une application faisant le lien entre des musiciens et les groupes musicaux auxquels ils appartiennent. Une relation plusieurs-à-plusieurs existe entre une personne et les groupes dont elle est membre, il est donc possible d’utiliser un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> pour représenter cette relation. Cependant, il y a de nombreux détails au sujet de l’appartenance au groupe qu’il peut être intéressant de conserver, comme par exemple la date à laquelle la personne à rejoint le groupe.</p>\n<p>Pour ces situations, Django permet d’indiquer le modèle qui sera utilisé pour spécifier la relation plusieurs-à-plusieurs. Il est alors possible de définir des champs supplémentaires dans le modèle intermédiaire. Ce dernier est associé au champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> en utilisant le paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField.through\" title=\"django.db.models.ManyToManyField.through\"><code class=\"xref py py-attr docutils literal notranslate\">through</code></a> qui va pointer vers le modèle agissant comme intermédiaire. Dans notre exemple de musique, le code pourrait ressembler à ceci :</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    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">128</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>              <span class=\"c1\"># __unicode__ on Python 2</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>name\n\n<span class=\"k\">class</span> <span class=\"nc\">Group</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">128</span><span class=\"p\">)</span>\n    members <span class=\"o\">=</span> models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span>Person<span class=\"p\">,</span> through<span class=\"o\">=</span><span class=\"s1\">&#39;Membership&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>              <span class=\"c1\"># __unicode__ on Python 2</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>name\n\n<span class=\"k\">class</span> <span class=\"nc\">Membership</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    person <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Person<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    group <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Group<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    date_joined <span class=\"o\">=</span> models<span class=\"o\">.</span>DateField<span class=\"p\">()</span>\n    invite_reason <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Lorsque vous définissez le modèle intermédiaire, vous indiquez explicitement les clés étrangères vers les modèles impliqués dans la relation plusieurs-à-plusieurs. Cette déclaration explicite définit comment les deux modèles sont reliés.</p>\n<p>Il y a quelques restrictions concernant le modèle intermédiaire :</p>\n<ul class=\"simple\">\n<li><p>Le modèle intermédiaire doit contenir une et une seule clé étrangère vers le modèle source (qui correspondrait à <code class=\"docutils literal notranslate\">Group</code> dans notre exemple), ou alors vous devez explicitement indiquer à Django les clés étrangères à employer pour les relations en utilisant <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField.through_fields\" title=\"django.db.models.ManyToManyField.through_fields\"><code class=\"xref py py-attr docutils literal notranslate\">ManyToManyField.through_fields</code></a>. S’il y a plus d’une clé étrangère et que <code class=\"docutils literal notranslate\">through_fields</code> n’est pas précisé, une erreur de validation est produite. C’est exactement le même procédé pour la clé étrangère vers le modèle cible (qui correspondrait à <code class=\"docutils literal notranslate\">Person</code> dans notre exemple).</p></li>\n<li><p>Pour un modèle ayant une relation plusieurs-à-plusieurs avec lui-même au travers d’un modèle intermédiaire, deux clés étrangères vers le même modèle sont autorisées, mais elles seront considérées comme les deux (différentes) parties de la relation plusieurs-à-plusieurs. Mais s’il y a <em>plus</em> de deux clés étrangères, vous devez aussi indiquer <code class=\"docutils literal notranslate\">through_fields</code> comme ci-dessus, sinon une erreur de validation sera générée.</p></li>\n<li><p>Lors de la définition d’une relation plusieurs-à-plusieurs d’un modèle vers lui-même au travers d’un modèle intermédiaire, vous <em>devez</em> employer le paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField.symmetrical\" title=\"django.db.models.ManyToManyField.symmetrical\"><code class=\"xref py py-attr docutils literal notranslate\">symmetrical=False</code></a> (voir la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#manytomany-arguments\"><span class=\"std std-ref\">référence des champs de modèle</span></a>).</p></li>\n</ul>\n<p>Après avoir configuré le champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> afin qu’il utilise le modèle intermédiaire (<code class=\"docutils literal notranslate\">Membership</code>, dans ce cas), tout est prêt pour commencer à créer des relations plusieurs-à-plusieurs. Cela s’effectue en créant des instances du modèle intermédiaire :</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>ringo <span class=\"o\">=</span> Person<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Ringo Starr&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>paul <span class=\"o\">=</span> Person<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Paul McCartney&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>beatles <span class=\"o\">=</span> Group<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;The Beatles&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>m1 <span class=\"o\">=</span> Membership<span class=\"p\">(</span>person<span class=\"o\">=</span>ringo<span class=\"p\">,</span> group<span class=\"o\">=</span>beatles<span class=\"p\">,</span>\n<span class=\"gp\">... </span>    date_joined<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">1962</span><span class=\"p\">,</span> <span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"mi\">16</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>    invite_reason<span class=\"o\">=</span><span class=\"s2\">&quot;Needed a new drummer.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>m1<span class=\"o\">.</span>save<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>beatles<span class=\"o\">.</span>members<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">[&lt;Person: Ringo Starr&gt;]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>ringo<span class=\"o\">.</span>group_set<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">[&lt;Group: The Beatles&gt;]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>m2 <span class=\"o\">=</span> Membership<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>person<span class=\"o\">=</span>paul<span class=\"p\">,</span> group<span class=\"o\">=</span>beatles<span class=\"p\">,</span>\n<span class=\"gp\">... </span>    date_joined<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">1960</span><span class=\"p\">,</span> <span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>    invite_reason<span class=\"o\">=</span><span class=\"s2\">&quot;Wanted to form a band.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>beatles<span class=\"o\">.</span>members<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">[&lt;Person: Ringo Starr&gt;, &lt;Person: Paul McCartney&gt;]</span>\n</code></pre></div>\n<p>Au contraire des champs plusieurs-à-plusieurs normaux, il n’est <em>pas</em> possible d’utiliser <code class=\"docutils literal notranslate\">add</code>, <code class=\"docutils literal notranslate\">create</code> ou l’attribution (par ex. <code class=\"docutils literal notranslate\">beatles.members = [...]</code>) pour créer des relations :</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\"># THIS WILL NOT WORK</span>\n<span class=\"o\">&gt;&gt;&gt;</span> beatles<span class=\"o\">.</span>members<span class=\"o\">.</span>add<span class=\"p\">(</span>john<span class=\"p\">)</span>\n<span class=\"c1\"># NEITHER WILL THIS</span>\n<span class=\"o\">&gt;&gt;&gt;</span> beatles<span class=\"o\">.</span>members<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;George Harrison&quot;</span><span class=\"p\">)</span>\n<span class=\"c1\"># AND NEITHER WILL THIS</span>\n<span class=\"o\">&gt;&gt;&gt;</span> beatles<span class=\"o\">.</span>members <span class=\"o\">=</span> <span class=\"p\">[</span>john<span class=\"p\">,</span> paul<span class=\"p\">,</span> ringo<span class=\"p\">,</span> george<span class=\"p\">]</span>\n</code></pre></div>\n<p>Pourquoi ? Il n’est pas possible de simplement créer une relation entre une <code class=\"docutils literal notranslate\">Person</code> et un <code class=\"docutils literal notranslate\">Group</code>, car il est nécessaire d’indiquer tous les détails de la relation imposés par le modèle <code class=\"docutils literal notranslate\">Membership</code>. Les appels simples <code class=\"docutils literal notranslate\">add</code>, <code class=\"docutils literal notranslate\">create</code> ainsi que l’attribution ne permettent pas d’indiquer les détails supplémentaires. En conséquence, ils sont désactivés pour les relations plusieurs-à-plusieurs qui utilisent un modèle intermédiaire. La seule manière de créer ce type de relation est de créer des instances du modèle intermédiaire.</p>\n<p>La méthode <a class=\"reference internal\" href=\"/fr/1.9/ref/models/relations/#django.db.models.fields.related.RelatedManager.remove\" title=\"django.db.models.fields.related.RelatedManager.remove\"><code class=\"xref py py-meth docutils literal notranslate\">remove()</code></a> est désactivée pour les mêmes raisons. Toutefois, la méthode <a class=\"reference internal\" href=\"/fr/1.9/ref/models/relations/#django.db.models.fields.related.RelatedManager.clear\" title=\"django.db.models.fields.related.RelatedManager.clear\"><code class=\"xref py py-meth docutils literal notranslate\">clear()</code></a> peut être utilisée pour enlever toutes les relations plusieurs-à-plusieurs d’une instance :</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=\"c1\"># Beatles have broken up</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>beatles<span class=\"o\">.</span>members<span class=\"o\">.</span>clear<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Note that this deletes the intermediate model instances</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Membership<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">[]</span>\n</code></pre></div>\n<p>Après avoir établi des relations plusieurs-à-plusieurs en créant des instances du modèle intermédiaire, il est possible d’effectuer des requêtes. Comme pour une relation plusieurs-à-plusieurs normale, les requêtes peuvent utiliser les attributs du modèle lié à la relation plusieurs-à-plusieurs :</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\"># Find all the groups with a member whose name starts with &#39;Paul&#39;</span>\n<span class=\"o\">&gt;&gt;&gt;</span> Group<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>members__name__startswith<span class=\"o\">=</span><span class=\"s1\">&#39;Paul&#39;</span><span class=\"p\">)</span>\n<span class=\"p\">[</span><span class=\"o\">&lt;</span>Group<span class=\"p\">:</span> The Beatles<span class=\"o\">&gt;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>Comme vous utilisez un modèle intermédiaire, la requête peut aussi exploiter ses attributs :</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\"># Find all the members of the Beatles that joined after 1 Jan 1961</span>\n<span class=\"o\">&gt;&gt;&gt;</span> Person<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"o\">...</span>     group__name<span class=\"o\">=</span><span class=\"s1\">&#39;The Beatles&#39;</span><span class=\"p\">,</span>\n<span class=\"o\">...</span>     membership__date_joined__gt<span class=\"o\">=</span>date<span class=\"p\">(</span><span class=\"mi\">1961</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n<span class=\"p\">[</span><span class=\"o\">&lt;</span>Person<span class=\"p\">:</span> Ringo Starr<span class=\"p\">]</span>\n</code></pre></div>\n<p>Si vous avez besoin d’accéder aux informations d’appartenance au groupe, c’est possible de le faire en interrogeant directement le modèle <code class=\"docutils literal notranslate\">Membership</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>ringos_membership <span class=\"o\">=</span> Membership<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>group<span class=\"o\">=</span>beatles<span class=\"p\">,</span> person<span class=\"o\">=</span>ringo<span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>ringos_membership<span class=\"o\">.</span>date_joined\n<span class=\"go\">datetime.date(1962, 8, 16)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>ringos_membership<span class=\"o\">.</span>invite_reason\n<span class=\"go\">&#39;Needed a new drummer.&#39;</span>\n</code></pre></div>\n<p>Une autre façon d’accéder à la même information est d’interroger la <a class=\"reference internal\" href=\"/fr/1.9/topics/db/queries/#m2m-reverse-relationships\"><span class=\"std std-ref\">relation plusieurs-à-plusieurs inverse</span></a> à partir d’un objet <code class=\"docutils literal notranslate\">Person</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>ringos_membership <span class=\"o\">=</span> ringo<span class=\"o\">.</span>membership_set<span class=\"o\">.</span>get<span class=\"p\">(</span>group<span class=\"o\">=</span>beatles<span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>ringos_membership<span class=\"o\">.</span>date_joined\n<span class=\"go\">datetime.date(1962, 8, 16)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>ringos_membership<span class=\"o\">.</span>invite_reason\n<span class=\"go\">&#39;Needed a new drummer.&#39;</span>\n</code></pre></div>\n</section>\n<section id=\"one-to-one-relationships\">\n<h4>Relations un-à-un<a class=\"heading-anchor\" href=\"#one-to-one-relationships\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Pour définir une relation un-à-un, utilisez <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a>. Son utilisation est pareille à celle des autres types de champs <code class=\"docutils literal notranslate\">Field</code>: il s’agit d’un attribut de classe d’un modèle.</p>\n<p>Son utilisation principale concerne la clé primaire d’un objet lorsque cet objet « complète » un autre objet d’une certaine manière.</p>\n<p><a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> exige un paramètre positionnel : la classe à laquelle le modèle est lié.</p>\n<p>Par exemple, si vous construisiez une base de données d”« emplacements » (<code class=\"docutils literal notranslate\">Place</code> dans l’exemple), il s’agirait de mettre en place des éléments assez standards comme l’adresse, le numéro de téléphone, etc. dans la base de données. Ensuite, si vous souhaitez construire une base de données de restaurants au-dessus de la base des emplacements, au lieu de vous répéter et de répliquer tous ces champs dans le modèle <code class=\"docutils literal notranslate\">Restaurant</code>, il serait possible de concevoir <code class=\"docutils literal notranslate\">Restaurant</code> avec un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> vers <code class=\"docutils literal notranslate\">Place</code> (parce qu’un restaurant « est un » emplacement ; en fait, pour gérer cela, vous feriez probablement appel à de l”<a class=\"reference internal\" href=\"#model-inheritance\"><span class=\"std std-ref\">héritage</span></a>, ce qui implique une relation un-à-un implicite).</p>\n<p>Comme pour <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a>, il est aussi possible de créer des <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#recursive-relationships\"><span class=\"std std-ref\">relations récursives</span></a> et des <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#lazy-relationships\"><span class=\"std std-ref\">relations vers des modèles non encore définis</span></a>.</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">Voir aussi</p>\n<p>Consultez les <a class=\"reference internal\" href=\"/fr/1.9/topics/db/examples/one_to_one/\"><span class=\"doc\">exemples de relations un-à-un entre modèles</span></a> pour voir un exemple complet.</p>\n</aside>\n<p>Les champs <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> acceptent aussi un paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField.parent_link\" title=\"django.db.models.OneToOneField.parent_link\"><code class=\"xref py py-attr docutils literal notranslate\">parent_link</code></a> facultatif.</p>\n<p>Précédemment, les classes <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> devenaient automatiquement la clé primaire d’un modèle. Cela n’est plus le cas (même si il est toujours possible de passer manuellement le paramètre <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">primary_key</code></a> si vous le voulez). Il est donc possible d’avoir plusieurs champs <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> dans un seul modèle.</p>\n</section>\n</section>\n<section id=\"models-across-files\">\n<h3>Modèles dans plusieurs fichiers<a class=\"heading-anchor\" href=\"#models-across-files\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il est parfaitement admis de lier un modèle à celui d’une autre application. Pour cela, importez le modèle à lier au sommet du fichier où votre modèle est défini. Puis, il suffit de faire référence à cette autre classe de modèle là où c’est nécessaire. 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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">geography.models</span> <span class=\"kn\">import</span> ZipCode\n\n<span class=\"k\">class</span> <span class=\"nc\">Restaurant</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    zip_code <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>\n        ZipCode<span class=\"p\">,</span>\n        on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>SET_NULL<span class=\"p\">,</span>\n        blank<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n        null<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"field-name-restrictions\">\n<h3>Restrictions sur les noms de champs<a class=\"heading-anchor\" href=\"#field-name-restrictions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django ne soumet les noms de champs de modèles qu’à deux restrictions :</p>\n<ol class=\"arabic\">\n<li><p>Un nom de champ ne peut pas être un mot réservé de Python, car il en résulterait une erreur de syntaxe Python. 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=\"nc\">Example</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"k\">pass</span> <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span> <span class=\"c1\"># &#39;pass&#39; is a reserved word!</span>\n</code></pre></div>\n</li>\n<li><p>Un nom de champ ne peut pas contenir deux soulignements suivis, en raison du fonctionnement de la syntaxe Django pour les requêtes. 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=\"nc\">Example</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    foo__bar <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span> <span class=\"c1\"># &#39;foo__bar&#39; has two underscores!</span>\n</code></pre></div>\n</li>\n</ol>\n<p>Ces limites peuvent être contournées, car le nom de champ n’est pas nécessairement égal au nom de la colonne de base de données. Voir l’option <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field.db_column\" title=\"django.db.models.Field.db_column\"><code class=\"xref py py-attr docutils literal notranslate\">db_column</code></a>.</p>\n<p>Les mots réservés SQL, comme <code class=\"docutils literal notranslate\">join</code>, <code class=\"docutils literal notranslate\">where</code> ou <code class=\"docutils literal notranslate\">select</code> <em>sont</em> autorisés comme noms de champs de modèle, car Django échappe tous les noms de tables ou de colonnes de base de données dans toutes les requêtes SQL sous-jacentes. Il utilise la syntaxe de guillemets propre au moteur de base de données utilisé.</p>\n</section>\n<section id=\"custom-field-types\">\n<h3>Types de champs personnalisés<a class=\"heading-anchor\" href=\"#custom-field-types\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si aucun des champs de modèle existants ne convient à vos besoins, ou si vous souhaitez tirer profit d’un type de colonne de base de données plus spécialisé, vous pouvez créer votre propre classe de champ. Une documentation complète sur la création de champs personnalisés se trouve dans <a class=\"reference internal\" href=\"/fr/1.9/howto/custom-model-fields/\"><span class=\"doc\">Écriture de champs de modèles personnalisés</span></a>.</p>\n</section>\n</section>\n<section id=\"meta-options\">\n<span id=\"id3\"></span><h2>Options de <code class=\"docutils literal notranslate\">Meta</code><a class=\"heading-anchor\" href=\"#meta-options\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Vous pouvez attribuer des métadonnées à votre modèle en utilisant une classe <code class=\"docutils literal notranslate\">Meta</code> imbriquée, comme ceci :</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\">Ox</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    horn_length <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span>\n\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        ordering <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;horn_length&quot;</span><span class=\"p\">]</span>\n        verbose_name_plural <span class=\"o\">=</span> <span class=\"s2\">&quot;oxen&quot;</span>\n</code></pre></div>\n<p>Les métadonnées de modèles sont « tout ce qui n’est pas un champ », comme les options de tri (<a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.ordering\" title=\"django.db.models.Options.ordering\"><code class=\"xref py py-attr docutils literal notranslate\">ordering</code></a>), le nom de la table de base de données (<a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.db_table\" title=\"django.db.models.Options.db_table\"><code class=\"xref py py-attr docutils literal notranslate\">db_table</code></a>) ou des noms verbeux singulier et pluriel (<a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.verbose_name\" title=\"django.db.models.Options.verbose_name\"><code class=\"xref py py-attr docutils literal notranslate\">verbose_name</code></a> et <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.verbose_name_plural\" title=\"django.db.models.Options.verbose_name_plural\"><code class=\"xref py py-attr docutils literal notranslate\">verbose_name_plural</code></a>). Aucune n’est obligatoire et la présence de <code class=\"docutils literal notranslate\">class Meta</code> dans un modèle est entièrement facultative.</p>\n<p>Une liste complète de toutes les options <code class=\"docutils literal notranslate\">Meta</code> possibles se trouve dans la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/\"><span class=\"doc\">référence des options de modèle</span></a>.</p>\n</section>\n<section id=\"model-attributes\">\n<span id=\"id4\"></span><h2>Les attributs de modèle<a class=\"heading-anchor\" href=\"#model-attributes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"simple\">\n<dt><code class=\"docutils literal notranslate\">objects</code></dt><dd><p>L’attribut le plus important d’un modèle est le <a class=\"reference internal\" href=\"/fr/1.9/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a>. Il s’agit de l’interface par laquelle les modèles Django ont accès aux opérations de requêtes vers la base de données et par laquelle les <a class=\"reference internal\" href=\"/fr/1.9/topics/db/queries/#retrieving-objects\"><span class=\"std std-ref\">instances de modèles sont construites</span></a> à partir de la base de données. Si aucun objet <code class=\"docutils literal notranslate\">Manager</code> (gestionnaire) personnalisé n’est indiqué, le nom par défaut est <a class=\"reference internal\" href=\"/fr/1.9/ref/models/class/#django.db.models.Model.objects\" title=\"django.db.models.Model.objects\"><code class=\"xref py py-attr docutils literal notranslate\">objects</code></a>. Les gestionnaires ne sont accessibles qu’au travers des classes de modèle, et pas des instances de modèle.</p>\n</dd>\n</dl>\n</section>\n<section id=\"model-methods\">\n<span id=\"id5\"></span><h2>Méthodes des modèles<a class=\"heading-anchor\" href=\"#model-methods\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Pour ajouter des fonctionnalités de « niveau ligne » à vos objets, définissez des méthodes personnalisées dans le modèle. Alors que les méthodes de <a class=\"reference internal\" href=\"/fr/1.9/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\">Manager</code></a> sont prévues pour agir au niveau des tables, les méthodes de modèles agissent plutôt sur une instance particulière d’un modèle.</p>\n<p>C’est une technique importante pour conserver la logique métier à un seul endroit, le modèle.</p>\n<p>Par exemple, ce modèle possède quelques méthodes 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=\"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    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    birth_date <span class=\"o\">=</span> models<span class=\"o\">.</span>DateField<span class=\"p\">()</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">baby_boomer_status</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;Returns the person&#39;s baby-boomer status.&quot;</span>\n        <span class=\"kn\">import</span> <span class=\"nn\">datetime</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span>birth_date <span class=\"o\">&lt;</span> datetime<span class=\"o\">.</span>date<span class=\"p\">(</span><span class=\"mi\">1945</span><span class=\"p\">,</span> <span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">):</span>\n            <span class=\"k\">return</span> <span class=\"s2\">&quot;Pre-boomer&quot;</span>\n        <span class=\"k\">elif</span> <span class=\"bp\">self</span><span class=\"o\">.</span>birth_date <span class=\"o\">&lt;</span> datetime<span class=\"o\">.</span>date<span class=\"p\">(</span><span class=\"mi\">1965</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">):</span>\n            <span class=\"k\">return</span> <span class=\"s2\">&quot;Baby boomer&quot;</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s2\">&quot;Post-boomer&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_get_full_name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;Returns the person&#39;s full name.&quot;</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\"> </span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span>first_name<span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span>last_name<span class=\"p\">)</span>\n    full_name <span class=\"o\">=</span> <span class=\"nb\">property</span><span class=\"p\">(</span>_get_full_name<span class=\"p\">)</span>\n</code></pre></div>\n<p>La dernière méthode de cet exemple est une <a class=\"reference internal\" href=\"/fr/1.9/glossary/#term-property\"><span class=\"xref std std-term\">propriété</span></a>.</p>\n<p>La <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/\"><span class=\"doc\">référence des instances de modèles</span></a> présente une liste complète des <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#model-instance-methods\"><span class=\"std std-ref\">méthodes automatiquement héritées par chaque modèle</span></a>. Vous pouvez surcharger la plupart d’entre elles, voir <a class=\"reference internal\" href=\"#overriding-predefined-model-methods\">surcharge des méthodes de modèles prédéfinies</a> ci-dessous, mais vous souhaiterez presque toujours définir certaines dans vos modèles :</p>\n<dl>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model.__str__\" title=\"django.db.models.Model.__str__\"><code class=\"xref py py-meth docutils literal notranslate\">__str__()</code></a> (Python 3)</dt><dd><p>Une « méthode magique » de Python qui renvoie une « représentation » unicode d’un objet. C’est ce que Python et Django utilisent chaque fois qu’une instance de modèle doit être transformée en une simple chaîne en vue d’être affichée. C’est par exemple le cas lorsqu’un objet doit être affiché dans une console interactive ou dans l’interface d’administration.</p>\n<p>Cette méthode devrait toujours être définie ; la valeur par défaut n’est vraiment pas très utile.</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\">__unicode__()</code> (Python 2)</dt><dd><p>Équivalent Python 2 de <code class=\"docutils literal notranslate\">__str__()</code>.</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model.get_absolute_url\" title=\"django.db.models.Model.get_absolute_url\"><code class=\"xref py py-meth docutils literal notranslate\">get_absolute_url()</code></a></dt><dd><p>Cette méthode indique à Django comment produire l’URL d’un objet. Django l’utilise dans son interface d’administration ainsi qu’à chaque fois qu’il a besoin de connaître l’URL d’un objet.</p>\n<p>Chaque objet possédant un URL permettant de l’identifier de manière unique devrait définir cette méthode.</p>\n</dd>\n</dl>\n<section id=\"overriding-predefined-model-methods\">\n<span id=\"overriding-model-methods\"></span><h3>Surcharge des méthodes de modèles prédéfinies<a class=\"heading-anchor\" href=\"#overriding-predefined-model-methods\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Un autre groupe de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#model-instance-methods\"><span class=\"std std-ref\">méthodes de modèles</span></a> recouvrent un ensemble de comportements liés à la base de données et sont susceptibles d’être personnalisées. En particulier, il est assez fréquent de vouloir modifier le fonctionnement de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> et de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model.delete\" title=\"django.db.models.Model.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a>.</p>\n<p>Vous êtes libre de surcharger ces méthodes (et toute autre méthode de modèle) pour modifier leur comportement.</p>\n<p>Un cas d’utilisation classique de surcharge des méthodes intégrées est lorsque vous souhaitez effectuer une action lors de l’enregistrement d’un objet. Par exemple (voir <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> pour de la documentation sur les paramètres acceptés) :</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\">Blog</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    tagline <span class=\"o\">=</span> models<span class=\"o\">.</span>TextField<span class=\"p\">()</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">save</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        do_something<span class=\"p\">()</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span>Blog<span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span>save<span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span> <span class=\"c1\"># Call the &quot;real&quot; save() method.</span>\n        do_something_else<span class=\"p\">()</span>\n</code></pre></div>\n<p>Vous pouvez aussi empêcher l’enregistrement :</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\">Blog</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    tagline <span class=\"o\">=</span> models<span class=\"o\">.</span>TextField<span class=\"p\">()</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">save</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span>name <span class=\"o\">==</span> <span class=\"s2\">&quot;Yoko Ono&#39;s blog&quot;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"c1\"># Yoko shall never have her own blog!</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"nb\">super</span><span class=\"p\">(</span>Blog<span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span>save<span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span> <span class=\"c1\"># Call the &quot;real&quot; save() method.</span>\n</code></pre></div>\n<p>Il est important de ne pas oublier d’appeler la méthode de la classe parente (c’est l’affaire de <code class=\"docutils literal notranslate\">super(Blog, self).save(*args, **kwargs)</code>) pour s’assurer que l’objet soit bien enregistré dans la base de données. Si vous omettez d’appeler la méthode parente, le comportement par défaut n’est pas appliqué et la base de données ne sera pas affectée.</p>\n<p>Il est aussi important de transmettre les paramètres qui peuvent être acceptés par la méthode du modèle, c’est le rôle de <code class=\"docutils literal notranslate\">*args, **kwargs</code>. De temps à autre, Django étend les possibilités des méthodes de modèles intégrées en ajoutant de nouveaux paramètres. Si vous utilisez <code class=\"docutils literal notranslate\">*args, **kwargs</code> dans vos définitions de méthodes, vous êtes certain que votre code gérera automatiquement ces paramètres quand ils seront ajoutés.</p>\n<aside class=\"admonition-overridden-model-methods-are-not-called-on-bulk-operations admonition\" role=\"note\">\n<p class=\"admonition-title\">Les méthodes de modèle surchargées ne sont pas appelées dans les opérations groupées</p>\n<p>Notez que la méthode <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model.delete\" title=\"django.db.models.Model.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a> d’un objet n’est pas nécessairement appelée lorsque les <a class=\"reference internal\" href=\"/fr/1.9/topics/db/queries/#topics-db-queries-delete\"><span class=\"std std-ref\">objets sont supprimés en vrac en utilisant un QuerySet</span></a> ou par le truchement d’une <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.on_delete\" title=\"django.db.models.ForeignKey.on_delete\"><code class=\"xref py py-attr docutils literal notranslate\">suppression en cascade</code></a>. Pour être certain que la logique de suppression personnalisée soit exécutée, vous pouvez utiliser les signaux <a class=\"reference internal\" href=\"/fr/1.9/ref/signals/#django.db.models.signals.pre_delete\" title=\"django.db.models.signals.pre_delete\"><code class=\"xref py py-data docutils literal notranslate\">pre_delete</code></a> ou <a class=\"reference internal\" href=\"/fr/1.9/ref/signals/#django.db.models.signals.post_delete\" title=\"django.db.models.signals.post_delete\"><code class=\"xref py py-data docutils literal notranslate\">post_delete</code></a>.</p>\n<p>Malheureusement, il n’y a pas de solution possible lors de la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create\" title=\"django.db.models.query.QuerySet.bulk_create\"><code class=\"xref py py-meth docutils literal notranslate\">création</code></a> ou de la <a class=\"reference internal\" href=\"/fr/1.9/ref/models/querysets/#django.db.models.query.QuerySet.update\" title=\"django.db.models.query.QuerySet.update\"><code class=\"xref py py-meth docutils literal notranslate\">mise à jour</code></a> d’objets en vrac, puisque ni <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a>, ni <a class=\"reference internal\" href=\"/fr/1.9/ref/signals/#django.db.models.signals.pre_save\" title=\"django.db.models.signals.pre_save\"><code class=\"xref py py-data docutils literal notranslate\">pre_save</code></a>, ni <a class=\"reference internal\" href=\"/fr/1.9/ref/signals/#django.db.models.signals.post_save\" title=\"django.db.models.signals.post_save\"><code class=\"xref py py-data docutils literal notranslate\">post_save</code></a> ne sont appelés.</p>\n</aside>\n</section>\n<section id=\"executing-custom-sql\">\n<h3>Exécution de SQL personnalisé<a class=\"heading-anchor\" href=\"#executing-custom-sql\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Un autre usage assez fréquent est d’écrire des commandes SQL personnalisées dans les méthodes de modèles et les méthodes au niveau module. Pour plus de détails sur l’utilisation de SQL brut, consultez la documentation sur l”<a class=\"reference internal\" href=\"/fr/1.9/topics/db/sql/\"><span class=\"doc\">utilisation de SQL brut</span></a>.</p>\n</section>\n</section>\n<section id=\"model-inheritance\">\n<span id=\"id6\"></span><h2>Héritage de modèle<a class=\"heading-anchor\" href=\"#model-inheritance\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Dans Django, l’héritage de modèle fonctionne de manière presque identique à l’héritage des classes tel qu’il se pratique en Python, mais les éléments de base présentés au début de cette page sont toujours de mise. Cela signifie que la classe de base doit être une sous-classe de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/instances/#django.db.models.Model\" title=\"django.db.models.Model\"><code class=\"xref py py-class docutils literal notranslate\">django.db.models.Model</code></a>.</p>\n<p>La seule décision qui vous revient est de savoir si vous voulez que les modèles parents soient des modèles à part entière (avec leur propre table de base de données) ou si les parents ne sont que des conteneurs d’informations partagées qui ne seront visibles qu’au travers de leurs modèles enfants.</p>\n<p>Il existe trois types d’héritage possibles avec Django.</p>\n<ol class=\"arabic simple\">\n<li><p>Souvent, vous voulez simplement que la classe parente contienne des informations que vous ne souhaitez pas ressaisir dans chaque modèle enfant. Cette classe ne sera jamais utilisée pour elle-même, il s’agit donc de <a class=\"reference internal\" href=\"#abstract-base-classes\"><span class=\"std std-ref\">Classes de base abstraites</span></a>.</p></li>\n<li><p>Si vous héritez d’un modèle existant (provenant peut-être d’une toute autre application) et que vous souhaitez que chaque modèle dispose de sa propre table de base de données, il s’agit de <a class=\"reference internal\" href=\"#multi-table-inheritance\"><span class=\"std std-ref\">Héritage multi-table</span></a>.</p></li>\n<li><p>Finalement, si vous souhaitez uniquement modifier le comportement d’un modèle dans son code Python sans toucher aux champs de modèle, il s’agit de <a class=\"reference internal\" href=\"#proxy-models\"><span class=\"std std-ref\">Modèles mandataires</span></a>.</p></li>\n</ol>\n<section id=\"abstract-base-classes\">\n<span id=\"id7\"></span><h3>Classes de base abstraites<a class=\"heading-anchor\" href=\"#abstract-base-classes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les classes de base abstraites sont utiles lorsque vous souhaitez regrouper certaines informations communes à un ensemble de modèles. Vous rédigez la classe de base et indiquez <code class=\"docutils literal notranslate\">abstract=True</code> dans sa classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a>. Aucune table de base de données ne sera créée pour ce modèle. Par contre, lorsqu’elle sera utilisée comme classe de base pour d’autres modèles, ses champs seront ajoutés à ceux de la classe enfant. Il est considéré comme une erreur que d’avoir des champs de la classe de base abstraite ayant le même nom que ceux de la classe enfant (et Django lèvera une exception).</p>\n<p>Un 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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">CommonInfo</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    age <span class=\"o\">=</span> models<span class=\"o\">.</span>PositiveIntegerField<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\">Student</span><span class=\"p\">(</span>CommonInfo<span class=\"p\">):</span>\n    home_group <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Le modèle <code class=\"docutils literal notranslate\">Student</code> aura trois champs : <code class=\"docutils literal notranslate\">name</code>, <code class=\"docutils literal notranslate\">age</code> et <code class=\"docutils literal notranslate\">home_group</code>. Le modèle <code class=\"docutils literal notranslate\">CommonInfo</code> ne peut pas être utilisé comme un modèle Django normal, car c’est une classe de base abstraite. Ce modèle ne génère pas de table de base de données et ne possède pas de gestionnaire ; il ne peut pas être instancié ni enregistré directement.</p>\n<p>Dans beaucoup de situations, c’est ce type d’héritage de modèle qui convient. Il offre la possibilité de regrouper les informations communes au niveau Python, tout en ne créant qu’une table de base de données par modèle enfant.</p>\n<section id=\"meta-inheritance\">\n<h4>Héritage de <code class=\"docutils literal notranslate\">Meta</code><a class=\"heading-anchor\" href=\"#meta-inheritance\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Lorsqu’une classe de base abstraite est créée, Django rend disponible toute classe imbriquée <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> déclarée dans la classe de base comme attribut. Si une classe enfant ne déclare pas sa propre classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a>, elle hérite de la classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> de son parent. Si la classe enfant souhaite étendre la classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> du parent, elle peut en hériter. 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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">CommonInfo</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\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        ordering <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">]</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Student</span><span class=\"p\">(</span>CommonInfo<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">(</span>CommonInfo<span class=\"o\">.</span>Meta<span class=\"p\">):</span>\n        db_table <span class=\"o\">=</span> <span class=\"s1\">&#39;student_info&#39;</span>\n</code></pre></div>\n<p>Django effectue une seule modification à la classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> d’une classe de base abstraite : avant d’installer l’attribut <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a>, il définit <code class=\"docutils literal notranslate\">abstract=False</code>. Cela signifie que les enfants des classes de base abstraites ne deviennent pas automatiquement des classes abstraites elles-mêmes. Il est bien sûr possible de créer une classe de base abstraite qui hérite d’une autre classe abstraite. Il faut simplement se rappeler de définir explicitement <code class=\"docutils literal notranslate\">abstract=True</code> à chaque fois.</p>\n<p>Certains attributs n’ont pas de bonne raison d’être intégrés dans la classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> d’une classe de base abstraite. Par exemple, la présence de <code class=\"docutils literal notranslate\">db_table</code> signifierait que toutes les classes enfants (celles qui ne contiennent pas leur propre classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a>) utiliseraient la même table de base de données, ce qui ne serait certainement pas le comportement souhaité.</p>\n</section>\n<section id=\"be-careful-with-related-name\">\n<span id=\"abstract-related-name\"></span><h4>Soyez prudent avec <code class=\"docutils literal notranslate\">related_name</code><a class=\"heading-anchor\" href=\"#be-careful-with-related-name\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si vous utilisez l’attribut <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a> d’un champ <code class=\"docutils literal notranslate\">ForeignKey</code> ou <code class=\"docutils literal notranslate\">ManyToManyField</code>, vous devez toujours indiquer un nom inverse <em>unique</em> pour le champ. Cela produirait normalement un problème dans les classes de base abstraites, puisque les champs de cette classe sont inclus dans toutes les classes enfants avec exactement les mêmes valeurs d’attributs (y compris <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a>) à chaque fois.</p>\n<p>Pour contourner ce problème, lorsque vous utilisez <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a> dans une classe de base abstraite (et dans ce cas seulement), des parties du nom doivent contenir <code class=\"docutils literal notranslate\">'%(app_label)s'</code> et <code class=\"docutils literal notranslate\">'%(class)s'</code>.</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">'%(class)s'</code> est remplacé par le nom en minuscules de la classe enfant dans laquelle est utilisé le champ.</p></li>\n<li><p><code class=\"docutils literal notranslate\">'%(app_label)s'</code> est remplacé par le nom en minuscules de l’application dans laquelle la classe enfant est contenue. Chaque nom d’application installée doit être unique et les noms de classes de modèles dans chaque application doivent également être uniques, il est donc garanti que le nom résultant sera chaque fois différent.</p></li>\n</ul>\n<p>Par exemple, étant donné une application <code class=\"docutils literal notranslate\">common/models.py</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\">Base</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    m2m <span class=\"o\">=</span> models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span>OtherModel<span class=\"p\">,</span> related_name<span class=\"o\">=</span><span class=\"s2\">&quot;</span><span class=\"si\">%(app_label)s</span><span class=\"s2\">_</span><span class=\"si\">%(class)s</span><span class=\"s2\">_related&quot;</span><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\">ChildA</span><span class=\"p\">(</span>Base<span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">ChildB</span><span class=\"p\">(</span>Base<span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n<p>Accompagnée d’une autre application <code class=\"docutils literal notranslate\">rare/models.py</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\">common.models</span> <span class=\"kn\">import</span> Base\n\n<span class=\"k\">class</span> <span class=\"nc\">ChildB</span><span class=\"p\">(</span>Base<span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n<p>Le nom inverse du champ <code class=\"docutils literal notranslate\">common.ChildA.m2m</code> sera <code class=\"docutils literal notranslate\">common_childa_related</code>, alors que le nom inverse du champ <code class=\"docutils literal notranslate\">common.ChildB.m2m</code> sera <code class=\"docutils literal notranslate\">common_childb_related</code>, et finalement, le nom inverse du champ <code class=\"docutils literal notranslate\">rare.ChildB.m2m</code> sera <code class=\"docutils literal notranslate\">rare_childb_related</code>. Vous êtes libre de choisir comment utiliser les portions <code class=\"docutils literal notranslate\">'%(class)s'</code> et <code class=\"docutils literal notranslate\">'%(app_label)s</code> pour construire le nom lié, mais si vous oubliez de les inclure, Django signalera des erreurs lors du lancement des vérifications systèmes (ou en lançant <a class=\"reference internal\" href=\"/fr/1.9/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a>).</p>\n<p>Si vous n’indiquez pas d’attribut <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a> pour un champ d’une classe de base abstraite, le nom inverse par défaut sera le nom de la classe enfant suivi par <code class=\"docutils literal notranslate\">'_set'</code>, comme cela se serait produit si vous aviez directement déclaré le champ dans la classe enfant. Par exemple, dans le code ci-dessus, si l’attribut <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a> avait été omis, le nom inverse du champ <code class=\"docutils literal notranslate\">m2m</code> aurait été <code class=\"docutils literal notranslate\">childa_set</code> dans le cas <code class=\"docutils literal notranslate\">ChildA</code> et <code class=\"docutils literal notranslate\">childb_set</code> pour le champ <code class=\"docutils literal notranslate\">ChildB</code>.</p>\n</section>\n</section>\n<section id=\"multi-table-inheritance\">\n<span id=\"id8\"></span><h3>Héritage multi-table<a class=\"heading-anchor\" href=\"#multi-table-inheritance\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Le deuxième type d’héritage de modèle pris en charge par Django est lorsque chaque modèle d’une hiérarchie est lui-même un modèle à part entière. À chaque modèle correspond une table de base de données qui peut être interrogée et créée individuellement. Cette relation d’héritage introduit des liens entre le modèle enfant et chacun de ses parents (via un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> automatique). 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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n<span class=\"k\">class</span> <span class=\"nc\">Place</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    address <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">80</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Restaurant</span><span class=\"p\">(</span>Place<span class=\"p\">):</span>\n    serves_hot_dogs <span class=\"o\">=</span> models<span class=\"o\">.</span>BooleanField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n    serves_pizza <span class=\"o\">=</span> models<span class=\"o\">.</span>BooleanField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Tous les champs de <code class=\"docutils literal notranslate\">Place</code> seront aussi disponible dans <code class=\"docutils literal notranslate\">Restaurant</code>, même si les données se trouveront dans des tables de base de données différentes. Ainsi, ces deux formes sont possibles :</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>Place<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Bob&#39;s Cafe&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Restaurant<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;Bob&#39;s Cafe&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si vous avez une <code class=\"docutils literal notranslate\">Place</code> qui est aussi un <code class=\"docutils literal notranslate\">Restaurant</code>, vous pouvez accéder à l’objet <code class=\"docutils literal notranslate\">Restaurant</code> depuis l’objet <code class=\"docutils literal notranslate\">Place</code> en utilisant le nom du modèle en minuscules :</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>p <span class=\"o\">=</span> Place<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">)</span>\n<span class=\"go\"># If p is a Restaurant object, this will give the child class:</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p<span class=\"o\">.</span>restaurant\n<span class=\"go\">&lt;Restaurant: ...&gt;</span>\n</code></pre></div>\n<p>Cependant, si dans l’exemple ci-dessus <code class=\"docutils literal notranslate\">p</code> n’était <em>pas</em> un <code class=\"docutils literal notranslate\">Restaurant</code> (soit parce qu’il a été créé directement comme un objet <code class=\"docutils literal notranslate\">Place</code> ou qu’il est le parent d’une autre classe), l’accès à <code class=\"docutils literal notranslate\">p.restaurant</code> aurait généré une exception <code class=\"docutils literal notranslate\">Restaurant.DoesNotExist</code>.</p>\n<section id=\"meta-and-multi-table-inheritance\">\n<h4><code class=\"docutils literal notranslate\">Meta</code> et l’héritage multi-table<a class=\"heading-anchor\" href=\"#meta-and-multi-table-inheritance\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Dans le cas de l’héritage multi-table, l’héritage de la classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> du parent n’a aucun intérêt pour la classe enfant. Toutes les options <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> ont déjà été appliquées à la classe parente et une nouvelle application n’amènerait qu’à des comportements contradictoires (a contrario du cas de la classe de base abstraite où la classe de base n’existe pas pour elle-même).</p>\n<p>Ainsi, un modèle enfant n’a pas accès à la classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a> de son parent. Cependant, il existe quelques cas limités où l’enfant hérite du comportement de son parent : si l’enfant n’indique pas d’attribut <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.ordering\" title=\"django.db.models.Options.ordering\"><code class=\"xref py py-attr docutils literal notranslate\">ordering</code></a> ou <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.get_latest_by\" title=\"django.db.models.Options.get_latest_by\"><code class=\"xref py py-attr docutils literal notranslate\">get_latest_by</code></a>, il hérite des attributs correspondants de son parent.</p>\n<p>Si le parent possède un ordre de tri mais que vous ne souhaitez pas que l’enfant ait un ordre de tri quelconque, vous pouvez le désactiver explicitement :</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\">ChildModel</span><span class=\"p\">(</span>ParentModel<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"c1\"># Remove parent&#39;s ordering effect</span>\n        ordering <span class=\"o\">=</span> <span class=\"p\">[]</span>\n</code></pre></div>\n</section>\n<section id=\"inheritance-and-reverse-relations\">\n<h4>Héritage et relations inverses<a class=\"heading-anchor\" href=\"#inheritance-and-reverse-relations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Comme l’héritage multi-table utilise un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> implicite pour lier l’enfant à son parent, il est possible d’accéder à l’enfant depuis le parent comme dans l’exemple ci-dessus. Cependant, il est fait usage du nom correspondant à la valeur par défaut de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a> pour les relations <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> and <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a>. Si vous ajoutez ces types de relations dans la sous-classe du modèle parent, vous <strong>devez</strong> renseigner l’attribut <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ForeignKey.related_name\" title=\"django.db.models.ForeignKey.related_name\"><code class=\"xref py py-attr docutils literal notranslate\">related_name</code></a> pour chacun de ces champs. Si vous l’oubliez, Django génère une erreur de validation.</p>\n<p>Par exemple, en se basant toujours sur la classe <code class=\"docutils literal notranslate\">Place</code> ci-dessus, créons une autre sous-classe avec un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Supplier</span><span class=\"p\">(</span>Place<span class=\"p\">):</span>\n    customers <span class=\"o\">=</span> models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span>Place<span class=\"p\">)</span>\n</code></pre></div>\n<p>Il en résulte une erreur :</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>Reverse query name <span class=\"k\">for</span> <span class=\"s1\">&#39;Supplier.customers&#39;</span> clashes <span class=\"k\">with</span> reverse query\nname <span class=\"k\">for</span> <span class=\"s1\">&#39;Supplier.place_ptr&#39;</span><span class=\"o\">.</span>\n\nHINT<span class=\"p\">:</span> Add <span class=\"ow\">or</span> change a related_name argument to the definition <span class=\"k\">for</span>\n<span class=\"s1\">&#39;Supplier.customers&#39;</span> <span class=\"ow\">or</span> <span class=\"s1\">&#39;Supplier.place_ptr&#39;</span><span class=\"o\">.</span>\n</code></pre></div>\n<p>L’ajout de <code class=\"docutils literal notranslate\">related_name</code> au champ <code class=\"docutils literal notranslate\">customers</code> comme ci-après permettrait de résoudre l’erreur : <code class=\"docutils literal notranslate\">models.ManyToManyField(Place, related_name='provider')</code>.</p>\n</section>\n<section id=\"specifying-the-parent-link-field\">\n<h4>Indication du champ de lien vers le parent<a class=\"heading-anchor\" href=\"#specifying-the-parent-link-field\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Comme déjà mentionné, Django crée automatiquement une relation <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> de la classe enfant vers tout modèle parent non abstrait. Si vous souhaitez contrôler le nom du champ de liaison vers le parent, vous pouvez ajouter votre propre champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> et définir  <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.OneToOneField.parent_link\" title=\"django.db.models.OneToOneField.parent_link\"><code class=\"xref py py-attr docutils literal notranslate\">parent_link=True</code></a> pour indiquer que ce champ est le champ de liaison vers la classe parente.</p>\n</section>\n</section>\n<section id=\"proxy-models\">\n<span id=\"id9\"></span><h3>Modèles mandataires<a class=\"heading-anchor\" href=\"#proxy-models\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lorsqu’on utilise l”<a class=\"reference internal\" href=\"#multi-table-inheritance\"><span class=\"std std-ref\">héritage multi-table</span></a>, une nouvelle table de base de données est créée pour chaque sous-classe d’un modèle. C’est normalement le comportement souhaité, dans la mesure où la sous-classe doit pouvoir stocker les champs de données supplémentaires qui ne figurent pas dans la classe de base. Cependant, dans certains cas, seul le comportement Python d’un modèle a besoin d’être modifié, peut-être pour changer le gestionnaire par défaut ou pour ajouter une nouvelle méthode.</p>\n<p>C’est l’objectif de l’héritage de modèle mandataire : créer un mandataire (« proxy ») du modèle d’origine. Vous pouvez créer, supprimer et mettre à jour des instances du modèle mandataire et toutes les données seront enregistrées comme si vous utilisiez le modèle d’origine (non mandataire). La différence est que vous pouvez modifier certaines choses dans le modèle mandataire comme le tri par défaut des modèles ou le gestionnaire par défaut, sans devoir toucher au modèle original.</p>\n<p>Les modèles mandataires sont déclarés comme des modèles normaux. Vous indiquez à Django qu’il s’agit de modèles mandataires en définissant l’attribut <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.proxy\" title=\"django.db.models.Options.proxy\"><code class=\"xref py py-attr docutils literal notranslate\">proxy</code></a> de la classe <code class=\"docutils literal notranslate\">Meta</code> à <code class=\"docutils literal notranslate\">True</code>.</p>\n<p>Par exemple, supposons que vous vouliez ajouter une méthode au modèle <code class=\"docutils literal notranslate\">Person</code>. Vous pouvez le faire de cette façon :</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    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\">30</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\">30</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">MyPerson</span><span class=\"p\">(</span>Person<span class=\"p\">):</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        proxy <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">do_something</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># ...</span>\n        <span class=\"k\">pass</span>\n</code></pre></div>\n<p>La classe <code class=\"docutils literal notranslate\">MyPerson</code> opère sur la même table de base de données que sa classe parente <code class=\"docutils literal notranslate\">Person</code>. En particulier, toute nouvelle instance de <code class=\"docutils literal notranslate\">Person</code> sera aussi accessible au travers de <code class=\"docutils literal notranslate\">MyPerson</code> et inversement :</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>p <span class=\"o\">=</span> Person<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>first_name<span class=\"o\">=</span><span class=\"s2\">&quot;foobar&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>MyPerson<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>first_name<span class=\"o\">=</span><span class=\"s2\">&quot;foobar&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;MyPerson: foobar&gt;</span>\n</code></pre></div>\n<p>Il est aussi possible d’utiliser un modèle mandataire pour définir un autre tri par défaut sur un modèle. Par exemple, vous ne voulez pas toujours trier le modèle <code class=\"docutils literal notranslate\">Person</code>, mais souvent le trier par <code class=\"docutils literal notranslate\">last_name</code> lorsque que vous utilisez le mandataire. C’est simple :</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\">OrderedPerson</span><span class=\"p\">(</span>Person<span class=\"p\">):</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        ordering <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;last_name&quot;</span><span class=\"p\">]</span>\n        proxy <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>Dorénavant les requêtes sur <code class=\"docutils literal notranslate\">Person</code> ne seront pas triées mais les requêtes sur <code class=\"docutils literal notranslate\">OrderedPerson</code> seront triées par leur champ <code class=\"docutils literal notranslate\">last_name</code>.</p>\n<section id=\"querysets-still-return-the-model-that-was-requested\">\n<h4>Les requêtes <code class=\"docutils literal notranslate\">QuerySet</code> renvoient toujours le modèle interrogé<a class=\"heading-anchor\" href=\"#querysets-still-return-the-model-that-was-requested\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Il n’y a aucun moyen de demander à Django de renvoyer par exemple un objet <code class=\"docutils literal notranslate\">MyPerson</code> chaque fois que vous faites une requête sur des objets <code class=\"docutils literal notranslate\">Person</code>. Une requête sur des objets``Person`` renvoie toujours des objets de ce même type. L’idée principale des objets mandataires est que le code se basant sur l’objet <code class=\"docutils literal notranslate\">Person</code> original utilise ces objets-là et que votre propre code peut utiliser les extensions que vous avez rajoutées (et qu’aucun autre code ne peut utiliser de toute manière). Ce n’est pas une façon de remplacer partout le modèle <code class=\"docutils literal notranslate\">Person</code> (ou un autre) par un autre modèle de votre conception.</p>\n</section>\n<section id=\"base-class-restrictions\">\n<h4>Restrictions des classes de base<a class=\"heading-anchor\" href=\"#base-class-restrictions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Un modèle mandataire ne peut hériter que d’une seule classe de modèle non abstraite. Il n’est pas possible d’hériter de plusieurs modèles non abstraits car le modèle mandataire ne fournit aucune connexion entre les lignes de différentes tables de base de données. Un modèle mandataire peut hériter d’autant de classes de modèle abstraites que nécessaire pourvu qu’elles ne définissent <em>pas</em> de champ de modèle.</p>\n</section>\n<section id=\"proxy-model-managers\">\n<h4>Gestionnaires des modèles mandataires<a class=\"heading-anchor\" href=\"#proxy-model-managers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si vous n’indiquer aucun gestionnaire de modèle pour un modèle mandataire, il hérite des gestionnaires de ses modèles parents. Si vous définissez un gestionnaire sur le modèle mandataire, il devient le gestionnaire par défaut, bien que d’éventuels gestionnaires définis dans les classes parentes seront aussi disponibles.</p>\n<p>En poursuivant l’exemple ci-dessus, vous pourriez modifier le gestionnaire par défaut utilisé lors des requêtes sur le modèle <code class=\"docutils literal notranslate\">Person</code> comme ceci :</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\">NewManager</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Manager<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">pass</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">MyPerson</span><span class=\"p\">(</span>Person<span class=\"p\">):</span>\n    objects <span class=\"o\">=</span> NewManager<span class=\"p\">()</span>\n\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        proxy <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>Si vous souhaitez ajouter un nouveau gestionnaire au modèle mandataire sans remplacer celui qui est défini par défaut, vous pouvez employer les techniques décrites dans la documentation des <a class=\"reference internal\" href=\"/fr/1.9/topics/db/managers/#custom-managers-and-inheritance\"><span class=\"std std-ref\">gestionnaires personnalisés</span></a> : créez une classe de base contenant les nouveaux gestionnaires et héritez de celle-ci après la classe de base principale :</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\"># Create an abstract class for the new manager.</span>\n<span class=\"k\">class</span> <span class=\"nc\">ExtraManagers</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    secondary <span class=\"o\">=</span> NewManager<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\">MyPerson</span><span class=\"p\">(</span>Person<span class=\"p\">,</span> ExtraManagers<span class=\"p\">):</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        proxy <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>Il est assez rare d’avoir besoin de le faire, mais si besoin est, c’est possible.</p>\n</section>\n<section id=\"differences-between-proxy-inheritance-and-unmanaged-models\">\n<span id=\"proxy-vs-unmanaged-models\"></span><h4>Differences between proxy inheritance and unmanaged models<a class=\"heading-anchor\" href=\"#differences-between-proxy-inheritance-and-unmanaged-models\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>L’héritage des modèles mandataires est en apparence très semblable à la création de modèles non pilotés, utilisant l’attribut <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.managed\" title=\"django.db.models.Options.managed\"><code class=\"xref py py-attr docutils literal notranslate\">managed</code></a> de la classe <code class=\"docutils literal notranslate\">Meta</code> d’un modèle. Les deux alternatives ne sont pas totalement équivalentes et il vaut la peine d’évaluer laquelle correspond le mieux à votre besoin.</p>\n<p>Une des différences est que vous pouvez (et vous devez même, au risque d’obtenir un modèle vide) définir les champs des modèles ayant <code class=\"docutils literal notranslate\">Meta.managed=False</code>. Il est possible, en définissant soigneusement <a class=\"reference internal\" href=\"/fr/1.9/ref/models/options/#django.db.models.Options.db_table\" title=\"django.db.models.Options.db_table\"><code class=\"xref py py-attr docutils literal notranslate\">Meta.db_table</code></a>, de créer un modèle non piloté masquant un modèle existant et d’y ajouter des méthodes Python. Cependant, cette solution est très répétitive et fragile dans la mesure où il faut manuellement synchroniser les deux en cas de modifications.</p>\n<p>L’autre différence qui est plus importante pour les modèles mandataires est la façon dont les gestionnaires de modèles sont traités. Il est entendu que les modèles mandataires se comportent exactement de la même façon que leur modèle de base. Ils héritent des gestionnaires de modèles de leur parent, y compris du gestionnaire par défaut. Dans le cas habituel de l’héritage de modèle multi-table, les enfants n’héritent pas des gestionnaires de leur parent puisque les gestionnaires personnalisés ne sont pas toujours adéquats lorsque des champs supplémentaires entrent en jeu. La <a class=\"reference internal\" href=\"/fr/1.9/topics/db/managers/#custom-managers-and-inheritance\"><span class=\"std std-ref\">documentation des gestionnaires</span></a> présente plus de détails au sujet de cette dernière situation.</p>\n<p>Lorsque ces deux fonctionnalités ont été établies, il y a eu des tentatives d’en faire une seule solution. Il en est ressorti que les interactions avec l’héritage en général et avec les gestionnaires plus particulièrement rendaient l’API très compliquée et potentiellement difficile à comprendre et à utiliser. En conclusion, comme deux options étaient nécessaires dans tous les cas, c’est le scénario de la distinction actuelle qui a prévalu.</p>\n<p>Ainsi, les règles générales sont :</p>\n<ol class=\"arabic simple\">\n<li><p>Si vous reflétez un modèle ou une table de base de données existant et que vous ne souhaitez pas reproduire toutes les colonnes d’origine de la table, utilisez <code class=\"docutils literal notranslate\">Meta.managed=False</code>. Cette option est habituellement utile pour la modélisation de tables ou vues de base de données qui ne sont pas sous le contrôle de Django.</p></li>\n<li><p>Si votre objectif est de ne modifier que le comportement Python d’un modèle tout en conservant les mêmes champs que l’original, utilisez <code class=\"docutils literal notranslate\">Meta.proxy=True</code>. Cette configuration assure que le modèle mandataire est une copie exacte de la structure de stockage du modèle de base lorsque des données sont enregistrées.</p></li>\n</ol>\n</section>\n</section>\n<section id=\"multiple-inheritance\">\n<span id=\"model-multiple-inheritance-topic\"></span><h3>Héritage multiple<a class=\"heading-anchor\" href=\"#multiple-inheritance\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Tout comme l’héritage en Python, les modèles Django peuvent hériter de plusieurs modèles parents. N’oubliez pas que les règles Python habituelles de résolution de nom s’appliquent. La première classe de base dans laquelle apparaît un nom particulier (par ex. <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a>) prévaut sur les autres apparitions ; par exemple, cela signifie que si plusieurs parents contiennent une classe <a class=\"reference internal\" href=\"#meta-options\"><span class=\"std std-ref\">Meta</span></a>, seule la première occurrence sera utilisée, et toutes les autres seront ignorées.</p>\n<p>Généralement, il ne devrait pas être nécessaire d’hériter de plusieurs parents. La principale raison de le faire est dans le cas de classes « mix-in » : l’ajout d’un champ supplémentaire particulier ou d’une méthode dans chaque classe héritant de la classe « mix-in ». Essayez de garder votre hiérarchie d’héritage aussi simple et compréhensible que possible afin de ne pas devoir batailler au moment de retrouver la provenance d’une information ou d’un comportement spécifique.</p>\n<p>Notez qu’en héritant de plusieurs modèles possédant un champ de clé primaire <code class=\"docutils literal notranslate\">id</code> commun, une erreur sera signalée. Pour un héritage multiple correct, vous pouvez utiliser un champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.AutoField\" title=\"django.db.models.AutoField\"><code class=\"xref py py-class docutils literal notranslate\">AutoField</code></a> explicite dans les modèles 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=\"nc\">Article</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    article_id <span class=\"o\">=</span> models<span class=\"o\">.</span>AutoField<span class=\"p\">(</span>primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n    <span class=\"o\">...</span>\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    book_id <span class=\"o\">=</span> models<span class=\"o\">.</span>AutoField<span class=\"p\">(</span>primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n    <span class=\"o\">...</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">BookReview</span><span class=\"p\">(</span>Book<span class=\"p\">,</span> Article<span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n<p>Ou utiliser un ancêtre commun contenant le champ <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.AutoField\" title=\"django.db.models.AutoField\"><code class=\"xref py py-class docutils literal notranslate\">AutoField</code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Piece</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Article</span><span class=\"p\">(</span>Piece<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">Book</span><span class=\"p\">(</span>Piece<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">BookReview</span><span class=\"p\">(</span>Book<span class=\"p\">,</span> Article<span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n</section>\n<section id=\"field-name-hiding-is-not-permitted\">\n<h3>Le masquage de nom de champ n’est pas autorisé<a class=\"heading-anchor\" href=\"#field-name-hiding-is-not-permitted\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Dans l’héritage habituel de classes Python, il est permis de surcharger n’importe quel attribut de la classe parent par la classe enfant. Avec Django, cela n’est pas autorisé pour les attributs qui sont des instances de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> (en tout cas pas pour le moment). Si une classe de base possède un champ <code class=\"docutils literal notranslate\">auteur</code>, il n’est pas possible de créer un autre champ de modèle <code class=\"docutils literal notranslate\">auteur</code> dans les classes qui héritent de cette classe de base.</p>\n<p>La surcharge de champs de modèles parents pose des problèmes dans les domaines de l’initialisation de nouvelles instances (pour indiquer quel champ est initialisé dans <code class=\"docutils literal notranslate\">Model.__init__</code>) et de la sérialisation. Ce sont des situations qui n’affectent pas de la même manière l’héritage habituel de classes Python, cette différence entre l’héritage des classes Python et l’héritage des modèles Django n’est donc pas arbitraire.</p>\n<p>Cette restriction ne s’applique qu’aux attributs qui sont des instances de <a class=\"reference internal\" href=\"/fr/1.9/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a>. Les attributs Python normaux peuvent être surchargés sans problème. Cela ne s’applique aussi qu’au nom de l’attribut tel que Python le voit : si vous indiquez manuellement le nom de la colonne de base de données, il est possible d’avoir le même nom de colonne apparaissant à la fois dans un enfant et son modèle parent dans de l’héritage multi-table (ce sont finalement des colonnes appartenant à deux tables de base de données différentes).</p>\n<p>Django signale une erreur <a class=\"reference internal\" href=\"/fr/1.9/ref/exceptions/#django.core.exceptions.FieldError\" title=\"django.core.exceptions.FieldError\"><code class=\"xref py py-exc docutils literal notranslate\">FieldError</code></a> si vous surchargez un champ de modèle d’une classe parente.</p>\n</section>\n</section>\n<section id=\"organizing-models-in-a-package\">\n<h2>Organizing models in a package<a class=\"heading-anchor\" href=\"#organizing-models-in-a-package\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>The <a class=\"reference internal\" href=\"/fr/1.9/ref/django-admin/#django-admin-startapp\"><code class=\"xref std std-djadmin docutils literal notranslate\">manage.py startapp</code></a> command creates an application\nstructure that includes a <code class=\"docutils literal notranslate\">models.py</code> file. If you have many models,\norganizing them in separate files may be useful.</p>\n<p>To do so, create a <code class=\"docutils literal notranslate\">models</code> package. Remove <code class=\"docutils literal notranslate\">models.py</code> and create a\n<code class=\"docutils literal notranslate\">myapp/models/</code> directory with an <code class=\"docutils literal notranslate\">__init__.py</code> file and the files to\nstore your models. You must import the models in the <code class=\"docutils literal notranslate\">__init__.py</code> file.</p>\n<p>For example, if you had <code class=\"docutils literal notranslate\">organic.py</code> and <code class=\"docutils literal notranslate\">synthetic.py</code> in the <code class=\"docutils literal notranslate\">models</code>\ndirectory:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>myapp/models/__init__.py</code></figcaption><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=\"myapp/models/__init__.py\"><code><span class=\"kn\">from</span> <span class=\"nn\">.organic</span> <span class=\"kn\">import</span> Person\n<span class=\"kn\">from</span> <span class=\"nn\">.synthetic</span> <span class=\"kn\">import</span> Robot\n</code></pre></figure>\n<p>Explicitly importing each model rather than using <code class=\"docutils literal notranslate\">from .models import *</code>\nhas the advantages of not cluttering the namespace, making code more readable,\nand keeping code analysis tools useful.</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">Voir aussi</p>\n<dl class=\"simple\">\n<dt><a class=\"reference internal\" href=\"/fr/1.9/ref/models/\"><span class=\"doc\">La référence des modèles</span></a></dt><dd><p>Documente toutes les API liées aux modèles, y compris les champs de modèles, les objets liés et les requêtes (<code class=\"docutils literal notranslate\">QuerySet</code>).</p>\n</dd>\n</dl>\n</aside>\n</section>","rootId":"module-django.db.models","toc":[{"title":"Exemple rapide","anchor":"quick-example","children":[]},{"title":"Utilisation des modèles","anchor":"using-models","children":[]},{"title":"Champs","anchor":"fields","children":[{"title":"Types de champs","anchor":"field-types","children":[]},{"title":"Options des champs","anchor":"field-options","children":[]},{"title":"Champs clé primaire automatiques","anchor":"automatic-primary-key-fields","children":[]},{"title":"Noms de champs verbeux","anchor":"verbose-field-names","children":[]},{"title":"Relations","anchor":"relationships","children":[{"title":"Relations plusieurs-à-un","anchor":"many-to-one-relationships","children":[]},{"title":"Relations plusieurs-à-plusieurs","anchor":"many-to-many-relationships","children":[]},{"title":"Champs supplémentaires dans les relations plusieurs-à-plusieurs","anchor":"extra-fields-on-many-to-many-relationships","children":[]},{"title":"Relations un-à-un","anchor":"one-to-one-relationships","children":[]}]},{"title":"Modèles dans plusieurs fichiers","anchor":"models-across-files","children":[]},{"title":"Restrictions sur les noms de champs","anchor":"field-name-restrictions","children":[]},{"title":"Types de champs personnalisés","anchor":"custom-field-types","children":[]}]},{"title":"Options de Meta","anchor":"meta-options","children":[]},{"title":"Les attributs de modèle","anchor":"model-attributes","children":[]},{"title":"Méthodes des modèles","anchor":"model-methods","children":[{"title":"Surcharge des méthodes de modèles prédéfinies","anchor":"overriding-predefined-model-methods","children":[]},{"title":"Exécution de SQL personnalisé","anchor":"executing-custom-sql","children":[]}]},{"title":"Héritage de modèle","anchor":"model-inheritance","children":[{"title":"Classes de base abstraites","anchor":"abstract-base-classes","children":[{"title":"Héritage de Meta","anchor":"meta-inheritance","children":[]},{"title":"Soyez prudent avec related_name","anchor":"be-careful-with-related-name","children":[]}]},{"title":"Héritage multi-table","anchor":"multi-table-inheritance","children":[{"title":"Meta et l’héritage multi-table","anchor":"meta-and-multi-table-inheritance","children":[]},{"title":"Héritage et relations inverses","anchor":"inheritance-and-reverse-relations","children":[]},{"title":"Indication du champ de lien vers le parent","anchor":"specifying-the-parent-link-field","children":[]}]},{"title":"Modèles mandataires","anchor":"proxy-models","children":[{"title":"Les requêtes QuerySet renvoient toujours le modèle interrogé","anchor":"querysets-still-return-the-model-that-was-requested","children":[]},{"title":"Restrictions des classes de base","anchor":"base-class-restrictions","children":[]},{"title":"Gestionnaires des modèles mandataires","anchor":"proxy-model-managers","children":[]},{"title":"Differences between proxy inheritance and unmanaged models","anchor":"differences-between-proxy-inheritance-and-unmanaged-models","children":[]}]},{"title":"Héritage multiple","anchor":"multiple-inheritance","children":[]},{"title":"Le masquage de nom de champ n’est pas autorisé","anchor":"field-name-hiding-is-not-permitted","children":[]}]},{"title":"Organizing models in a package","anchor":"organizing-models-in-a-package","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/index","title":"Modèles et bases de données","url":"/fr/1.9/topics/db/"},"next":{"docname":"topics/db/queries","title":"Création de requêtes","url":"/fr/1.9/topics/db/queries/"},"formats":{"html":"/fr/1.9/topics/db/models/","markdown":"/fr/1.9/topics/db/models.md","json":"/fr/1.9/topics/db/models.json"},"source":"https://github.com/django/django/blob/stable/1.9.x/docs/topics/db/models.txt","official":"https://docs.djangoproject.com/fr/1.9/topics/db/models/","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"]}