{"title":"Référence des instances de modèles","version":"3.1","locale":"fr","docname":"ref/models/instances","url":"/fr/3.1/ref/models/instances/","canonical":"https://djangodocs.dev/fr/3.1/ref/models/instances/","summary":"Ce document détaille l’API des objets Model . Il augmente les contenus présentés dans les guides des modèles et des requêtes de base de données , il est donc…","html":"<h1>Référence des instances de modèles<a class=\"heading-anchor\" href=\"#model-instance-reference\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Ce document détaille l’API des objets <code class=\"docutils literal notranslate\"><span class=\"pre\">Model</span></code>. Il augmente les contenus présentés dans les guides des <a class=\"reference internal\" href=\"/fr/3.1/topics/db/models/\"><span class=\"doc\">modèles</span></a> et des <a class=\"reference internal\" href=\"/fr/3.1/topics/db/queries/\"><span class=\"doc\">requêtes de base de données</span></a>, il est donc conseillé de lire et de comprendre ces derniers avant de lire celui-ci.</p>\n<p>Tout au long de cette référence, nous utiliserons les <a class=\"reference internal\" href=\"/fr/3.1/topics/db/queries/#queryset-model-example\"><span class=\"std std-ref\">modèles d’exemple Weblog</span></a> présentés dans le <a class=\"reference internal\" href=\"/fr/3.1/topics/db/queries/\"><span class=\"doc\">guide des requêtes de base de données</span></a>.</p>\n<section id=\"creating-objects\">\n<h2>Création d’objets<a class=\"heading-anchor\" href=\"#creating-objects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Pour créer une nouvelle instance d’un modèle, instanciez-la comme n’importe quelle autre classe Python :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Model</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Les paramètres nommés sont les noms des champs définis dans le modèle. Notez que l’instanciation d’un modèle ne touche pas à la base de données ; pour cela, il faut enregistrer avec <a class=\"reference internal\" href=\"#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Vous pourriez être tenté de personnaliser le modèle en surchargeant sa méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code>. Cependant, si vous faites cela, prenez soin de ne pas modifier la signature de la méthode car tout changement pourrait bloquer l’enregistrement de l’instance de modèle. Plutôt que de surcharger <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code>, essayer d’utiliser l’une de ces approches :</p>\n<ol class=\"arabic\">\n<li><p>Ajouter une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">classmethod</span></code> sur la classe du modèle :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Book</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">create</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">,</span> <span class=\"n\">title</span><span class=\"p\">):</span>\n        <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"bp\">cls</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"o\">=</span><span class=\"n\">title</span><span class=\"p\">)</span>\n        <span class=\"c1\"># do something with the book</span>\n        <span class=\"k\">return</span> <span class=\"n\">book</span>\n\n<span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"s2\">&quot;Pride and Prejudice&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</li>\n<li><p>Ajouter une méthode dans un gestionnaire personnalisé (souvent plus judicieux) :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BookManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">create_book</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">title</span><span class=\"p\">):</span>\n        <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"o\">=</span><span class=\"n\">title</span><span class=\"p\">)</span>\n        <span class=\"c1\"># do something with the book</span>\n        <span class=\"k\">return</span> <span class=\"n\">book</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Book</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">BookManager</span><span class=\"p\">()</span>\n\n<span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create_book</span><span class=\"p\">(</span><span class=\"s2\">&quot;Pride and Prejudice&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</li>\n</ol>\n</aside>\n<section id=\"customizing-model-loading\">\n<h3>Personnalisation du chargement des modèles<a class=\"heading-anchor\" href=\"#customizing-model-loading\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.from_db\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">classmethod</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">from_db</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">db</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field_names</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">values</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.from_db\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">from_db()</span></code> peut être utilisée pour personnaliser la création des instances de modèles lors de leur chargement à partir de la base de données.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">db</span></code> contient l’alias de la base de données à partir de laquelle le modèle est chargé, <code class=\"docutils literal notranslate\"><span class=\"pre\">field_names</span></code> contient les noms de tous les champs chargés et <code class=\"docutils literal notranslate\"><span class=\"pre\">values</span></code> contient les valeurs chargées pour chaque champ de <code class=\"docutils literal notranslate\"><span class=\"pre\">field_names</span></code>. L’ordre des champs dans <code class=\"docutils literal notranslate\"><span class=\"pre\">field_names</span></code> est le même que dans <code class=\"docutils literal notranslate\"><span class=\"pre\">values</span></code>. Si tous les champs du modèle sont présents, <code class=\"docutils literal notranslate\"><span class=\"pre\">values</span></code> est toujours dans l’ordre attendu par <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code>. Cela signifie que l’instance peut être créée par <code class=\"docutils literal notranslate\"><span class=\"pre\">cls(*values)</span></code>. Si certains champs sont différés, ils n’apparaissent pas dans <code class=\"docutils literal notranslate\"><span class=\"pre\">field_names</span></code>. Dans ce cas, attribuez une valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.models.DEFERRED</span></code> à chacun des champs manquants.</p>\n<p>En plus de créer le nouveau modèle, la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">from_db()</span></code> doit définir les drapeaux <code class=\"docutils literal notranslate\"><span class=\"pre\">adding</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">db</span></code> de l’attribut <a class=\"reference internal\" href=\"#django.db.models.Model._state\" title=\"django.db.models.Model._state\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">_state</span></code></a>  de la nouvelle instance.</p>\n<p>Dans l’exemple ci-dessous, on voit comment mémoriser les valeurs des champs telles que chargées à partir de la base de donné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=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DEFERRED</span>\n\n<span class=\"nd\">@classmethod</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">from_db</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">,</span> <span class=\"n\">db</span><span class=\"p\">,</span> <span class=\"n\">field_names</span><span class=\"p\">,</span> <span class=\"n\">values</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Default implementation of from_db() (subject to change and could</span>\n    <span class=\"c1\"># be replaced with super()).</span>\n    <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">values</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">concrete_fields</span><span class=\"p\">):</span>\n        <span class=\"n\">values</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">values</span><span class=\"p\">)</span>\n        <span class=\"n\">values</span><span class=\"o\">.</span><span class=\"n\">reverse</span><span class=\"p\">()</span>\n        <span class=\"n\">values</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n            <span class=\"n\">values</span><span class=\"o\">.</span><span class=\"n\">pop</span><span class=\"p\">()</span> <span class=\"k\">if</span> <span class=\"n\">f</span><span class=\"o\">.</span><span class=\"n\">attname</span> <span class=\"ow\">in</span> <span class=\"n\">field_names</span> <span class=\"k\">else</span> <span class=\"n\">DEFERRED</span>\n            <span class=\"k\">for</span> <span class=\"n\">f</span> <span class=\"ow\">in</span> <span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">concrete_fields</span>\n        <span class=\"p\">]</span>\n    <span class=\"n\">instance</span> <span class=\"o\">=</span> <span class=\"bp\">cls</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">values</span><span class=\"p\">)</span>\n    <span class=\"n\">instance</span><span class=\"o\">.</span><span class=\"n\">_state</span><span class=\"o\">.</span><span class=\"n\">adding</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n    <span class=\"n\">instance</span><span class=\"o\">.</span><span class=\"n\">_state</span><span class=\"o\">.</span><span class=\"n\">db</span> <span class=\"o\">=</span> <span class=\"n\">db</span>\n    <span class=\"c1\"># customization to store the original field values on the instance</span>\n    <span class=\"n\">instance</span><span class=\"o\">.</span><span class=\"n\">_loaded_values</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">field_names</span><span class=\"p\">,</span> <span class=\"n\">values</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> <span class=\"n\">instance</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">save</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Check how the current values differ from ._loaded_values. For example,</span>\n    <span class=\"c1\"># prevent changing the creator_id of the model. (This example doesn&#39;t</span>\n    <span class=\"c1\"># support cases where &#39;creator_id&#39; is deferred).</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_state</span><span class=\"o\">.</span><span class=\"n\">adding</span> <span class=\"ow\">and</span> <span class=\"p\">(</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">creator_id</span> <span class=\"o\">!=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_loaded_values</span><span class=\"p\">[</span><span class=\"s1\">&#39;creator_id&#39;</span><span class=\"p\">]):</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Updating the value of creator isn&#39;t allowed&quot;</span><span class=\"p\">)</span>\n    <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>L’exemple ci-dessus montre une implémentation complète de <code class=\"docutils literal notranslate\"><span class=\"pre\">from_db()</span></code> pour clarifier son fonctionnement. Dans ce cas, il aurait été possible de faire appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">super()</span></code> dans la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">from_db()</span></code>.</p>\n</section>\n</section>\n<section id=\"refreshing-objects-from-database\">\n<h2>Actualisation des objets à partir de la base de données<a class=\"heading-anchor\" href=\"#refreshing-objects-from-database\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si vous supprimez un champ à partir d’une instance de modèle, un nouvel accès va recharger la valeur de la base de donné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=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">obj</span> <span class=\"o\">=</span> <span class=\"n\">MyModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">first</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">del</span> <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">field</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">field</span>  <span class=\"c1\"># Loads the field from the database</span>\n</code></pre></div>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.refresh_from_db\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">refresh_from_db</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fields</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.refresh_from_db\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Si vous avez besoin de recharger les valeurs d’un modèle à partir de la base de données, vous pouvez utiliser la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">refresh_from_db()</span></code>. Lorsque cette méthode est appelée sans paramètre, voici ce qui se passe :</p>\n<ol class=\"arabic simple\">\n<li><p>Tous les champs non différés du modèle sont mis à jour avec les valeurs actuellement présentes en base de données.</p></li>\n<li><p>Toutes les relations en cache sont effacées de l’instance rechargée.</p></li>\n</ol>\n<p>Seuls les champs du modèle sont rechargés à partir de la base de données. D’autres valeurs dépendantes de la base de données telles que les annotations ne sont pas rechargées. Tout attribut <a class=\"reference internal\" href=\"/fr/3.1/ref/utils/#django.utils.functional.cached_property\" title=\"django.utils.functional.cached_property\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">&#64;cached_property</span></code></a> n’est pas non plus réinitialisé.</p>\n<p>Le rechargement s’opère à partir de la base de données à l’origine des valeurs existantes, ou de la base de données par défaut si l’instance n’a pas été chargée à partir de la base de données. Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code> peut être utilisé pour forcer la base de données source du rechargement.</p>\n<p>Il est possible de forcer le groupe de champs à recharger en utilisant le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">fields</span></code>.</p>\n<p>Par exemple, pour tester qu’un appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">update()</span></code> a effectivement produit le résultat attendu, vous pourriez écrire un test semblable à celui-ci :</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\">def</span><span class=\"w\"> </span><span class=\"nf\">test_update_result</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"n\">obj</span> <span class=\"o\">=</span> <span class=\"n\">MyModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"n\">MyModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">pk</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">(</span><span class=\"n\">val</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;val&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"c1\"># At this point obj.val is still 1, but the value in the database</span>\n    <span class=\"c1\"># was updated to 2. The object&#39;s updated value needs to be reloaded</span>\n    <span class=\"c1\"># from the database.</span>\n    <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">refresh_from_db</span><span class=\"p\">()</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">val</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Notez que quand on accède à des champs différés, le chargement de la valeur différée du champ s’effectue avec cette méthode. Il est donc possible de personnaliser la manière de charger les données différées. L’exemple ci-dessous montre comment l’on peut recharger tous les champs d’une instance lorsqu’un champ différé est rechargé :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ExampleModel</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">refresh_from_db</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">using</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">fields</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"c1\"># fields contains the name of the deferred field to be</span>\n        <span class=\"c1\"># loaded.</span>\n        <span class=\"k\">if</span> <span class=\"n\">fields</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">fields</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">fields</span><span class=\"p\">)</span>\n            <span class=\"n\">deferred_fields</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_deferred_fields</span><span class=\"p\">()</span>\n            <span class=\"c1\"># If any deferred field is going to be loaded</span>\n            <span class=\"k\">if</span> <span class=\"n\">fields</span><span class=\"o\">.</span><span class=\"n\">intersection</span><span class=\"p\">(</span><span class=\"n\">deferred_fields</span><span class=\"p\">):</span>\n                <span class=\"c1\"># then load all of them</span>\n                <span class=\"n\">fields</span> <span class=\"o\">=</span> <span class=\"n\">fields</span><span class=\"o\">.</span><span class=\"n\">union</span><span class=\"p\">(</span><span class=\"n\">deferred_fields</span><span class=\"p\">)</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">refresh_from_db</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"p\">,</span> <span class=\"n\">fields</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n</code></pre></div>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.get_deferred_fields\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_deferred_fields</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.get_deferred_fields\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Une méthode utilitaire renvoyant un ensemble contenant les noms d’attributs de tous les champs d’un modèle qui sont actuellement différés.</p>\n</section>\n<section id=\"validating-objects\">\n<span id=\"id1\"></span><h2>Validation d’objets<a class=\"heading-anchor\" href=\"#validating-objects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La validation d’un modèle se déroule en trois étapes :</p>\n<ol class=\"arabic simple\">\n<li><p>Validation des champs de modèle - <a class=\"reference internal\" href=\"#django.db.models.Model.clean_fields\" title=\"django.db.models.Model.clean_fields\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.clean_fields()</span></code></a></p></li>\n<li><p>Validation du modèle en entier - <a class=\"reference internal\" href=\"#django.db.models.Model.clean\" title=\"django.db.models.Model.clean\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.clean()</span></code></a></p></li>\n<li><p>Validation de l’unicité des champs - <a class=\"reference internal\" href=\"#django.db.models.Model.validate_unique\" title=\"django.db.models.Model.validate_unique\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.validate_unique()</span></code></a></p></li>\n</ol>\n<p>Les trois étapes sont effectuées lorsque la méthode <a class=\"reference internal\" href=\"#django.db.models.Model.full_clean\" title=\"django.db.models.Model.full_clean\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">full_clean()</span></code></a> d’un modèle est appelée.</p>\n<p>Lors de l’utilisation d’un formulaire <a class=\"reference internal\" href=\"/fr/3.1/topics/forms/modelforms/#django.forms.ModelForm\" title=\"django.forms.ModelForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code></a>, l’appel à <a class=\"reference internal\" href=\"/fr/3.1/ref/forms/api/#django.forms.Form.is_valid\" title=\"django.forms.Form.is_valid\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">is_valid()</span></code></a> effectue ces étapes de validation pour tous les champs inclus dans le formulaire. Consultez la <a class=\"reference internal\" href=\"/fr/3.1/topics/forms/modelforms/\"><span class=\"doc\">documentation de ModelForm</span></a> pour plus d’informations. L’appel à la méthode <a class=\"reference internal\" href=\"#django.db.models.Model.full_clean\" title=\"django.db.models.Model.full_clean\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">full_clean()</span></code></a> d’un modèle ne devrait être nécessaire que lorsque l’on souhaite s’occuper soi-même des erreurs de validation ou si des champs ont été exclu du <a class=\"reference internal\" href=\"/fr/3.1/topics/forms/modelforms/#django.forms.ModelForm\" title=\"django.forms.ModelForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code></a> et qu’ils nécessitent une validation.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.full_clean\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">full_clean</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">exclude</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">validate_unique</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.full_clean\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Cette méthode appelle <a class=\"reference internal\" href=\"#django.db.models.Model.clean_fields\" title=\"django.db.models.Model.clean_fields\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.clean_fields()</span></code></a>, <a class=\"reference internal\" href=\"#django.db.models.Model.clean\" title=\"django.db.models.Model.clean\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.clean()</span></code></a> et <a class=\"reference internal\" href=\"#django.db.models.Model.validate_unique\" title=\"django.db.models.Model.validate_unique\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.validate_unique()</span></code></a> (si <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_unique</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>), dans cet ordre et peut générer une exception  <a class=\"reference internal\" href=\"/fr/3.1/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ValidationError</span></code></a> avec un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">message_dict</span></code> contenant les erreurs produites par les trois méthodes.</p>\n<p>Le paramètre facultatif <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude</span></code> peut être utilisé pour fournir une liste de noms de champs qui peuvent être exclus de la validation et du nettoyage. <a class=\"reference internal\" href=\"/fr/3.1/topics/forms/modelforms/#django.forms.ModelForm\" title=\"django.forms.ModelForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code></a> utilise ce paramètre pour exclure de la validation les champs qui sont absents du formulaire, car d’éventuelles erreurs ne pourraient pas être corrigées par l’utilisateur.</p>\n<p>Notez que <code class=\"docutils literal notranslate\"><span class=\"pre\">full_clean()</span></code> ne sera <em>pas</em> appelée automatiquement lorsque vous appelez la méthode <a class=\"reference internal\" href=\"#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a> d’un modèle. Il faut l’appeler manuellement au moment où vous souhaitez effectuer la validation de modèle pour vos propres modèles. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.exceptions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ValidationError</span>\n<span class=\"k\">try</span><span class=\"p\">:</span>\n    <span class=\"n\">article</span><span class=\"o\">.</span><span class=\"n\">full_clean</span><span class=\"p\">()</span>\n<span class=\"k\">except</span> <span class=\"n\">ValidationError</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n    <span class=\"c1\"># Do something based on the errors contained in e.message_dict.</span>\n    <span class=\"c1\"># Display them to a user, or handle them programmatically.</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n<p>La première chose que fait <code class=\"docutils literal notranslate\"><span class=\"pre\">full_clean()</span></code> est de procéder au nettoyage de chaque champ individuellement.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.clean_fields\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">clean_fields</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">exclude</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.clean_fields\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Cette méthode valide tous les champs du modèle. Le paramètre facultatif <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude</span></code> peut être utilisé pour fournir une liste de noms de champs à exclure de la validation. Une exception <a class=\"reference internal\" href=\"/fr/3.1/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ValidationError</span></code></a> est générée pour chaque champ dont la validation échoue.</p>\n<p>La deuxième chose que fait <code class=\"docutils literal notranslate\"><span class=\"pre\">full_clean()</span></code> est d’appeler <a class=\"reference internal\" href=\"#django.db.models.Model.clean\" title=\"django.db.models.Model.clean\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.clean()</span></code></a>. Cette méthode peut être surchargée pour effectuer une validation personnalisée du modèle.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.clean\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">clean</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.clean\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>C’est cette méthode qui devrait être utilisée pour fournir une validation de modèle personnalisée et pour modifier des attributs du modèle, le cas échéant. Par exemple, on pourrait profiter de cette méthode pour attribuer une valeur automatique à un champ ou pour procéder à une validation qui nécessite de pouvoir accéder à d’autres champs du modèle :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.exceptions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ValidationError</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.translation</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">gettext_lazy</span> <span class=\"k\">as</span> <span class=\"n\">_</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Article</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">clean</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Don&#39;t allow draft entries to have a pub_date.</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">status</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;draft&#39;</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pub_date</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">(</span><span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Draft entries may not have a publication date.&#39;</span><span class=\"p\">))</span>\n        <span class=\"c1\"># Set the pub_date for published items if it hasn&#39;t been set already.</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">status</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;published&#39;</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pub_date</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pub_date</span> <span class=\"o\">=</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">today</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Notez cependant que comme pour <a class=\"reference internal\" href=\"#django.db.models.Model.full_clean\" title=\"django.db.models.Model.full_clean\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.full_clean()</span></code></a>, la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">clean()</span></code> d’un modèle n’est pas invoquée lors d’un appel à la méthode <a class=\"reference internal\" href=\"#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a> du modèle.</p>\n<p>Dans l’exemple ci-dessus, l’exception <a class=\"reference internal\" href=\"/fr/3.1/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ValidationError</span></code></a> générée par <code class=\"docutils literal notranslate\"><span class=\"pre\">Model.clean()</span></code> a été créée en lui passant une chaîne, elle sera donc stockée dans une clé particulière d’un dictionnaire d’erreurs, <a class=\"reference internal\" href=\"/fr/3.1/ref/exceptions/#django.core.exceptions.NON_FIELD_ERRORS\" title=\"django.core.exceptions.NON_FIELD_ERRORS\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">NON_FIELD_ERRORS</span></code></a>. Cette clé est réservée aux erreurs liées au modèle dans son entier plutôt qu’à un champ spécifique :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.exceptions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">NON_FIELD_ERRORS</span><span class=\"p\">,</span> <span class=\"n\">ValidationError</span>\n<span class=\"k\">try</span><span class=\"p\">:</span>\n    <span class=\"n\">article</span><span class=\"o\">.</span><span class=\"n\">full_clean</span><span class=\"p\">()</span>\n<span class=\"k\">except</span> <span class=\"n\">ValidationError</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n    <span class=\"n\">non_field_errors</span> <span class=\"o\">=</span> <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">message_dict</span><span class=\"p\">[</span><span class=\"n\">NON_FIELD_ERRORS</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>Pour attribuer une exception à un champ particulier, créez une instance de <a class=\"reference internal\" href=\"/fr/3.1/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ValidationError</span></code></a> avec un dictionnaire dont les clés correspondent aux noms de champs. Nous pourrions mettre à jour l’exemple précédent en attribuant l’erreur au champ <code class=\"docutils literal notranslate\"><span class=\"pre\">pub_date</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Article</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">clean</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Don&#39;t allow draft entries to have a pub_date.</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">status</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;draft&#39;</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pub_date</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">({</span><span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">:</span> <span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Draft entries may not have a publication date.&#39;</span><span class=\"p\">)})</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>Si vous détectez des erreurs dans plusieurs champs pendant <code class=\"docutils literal notranslate\"><span class=\"pre\">Model.clean()</span></code>, il est aussi possible de passer un dictionnaire faisant correspondre des noms de champs aux erreurs :</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\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">({</span>\n    <span class=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"n\">ValidationError</span><span class=\"p\">(</span><span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Missing title.&#39;</span><span class=\"p\">),</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"s1\">&#39;required&#39;</span><span class=\"p\">),</span>\n    <span class=\"s1\">&#39;pub_date&#39;</span><span class=\"p\">:</span> <span class=\"n\">ValidationError</span><span class=\"p\">(</span><span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Invalid date.&#39;</span><span class=\"p\">),</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"s1\">&#39;invalid&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">})</span>\n</code></pre></div>\n<p>Finalement, <code class=\"docutils literal notranslate\"><span class=\"pre\">full_clean()</span></code> vérifie les contraintes d’unicité éventuelles du modèle.</p>\n<aside class=\"admonition-how-to-raise-field-specific-validation-errors-if-those-fields-don-t-appear-in-a-modelform admonition\">\n<p class=\"admonition-title\">Comment générer des erreurs de validation spécifiques à certains champs si ceux-ci n’apparaissent pas dans un <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code></p>\n<p>Il n’est pas possible de générer des erreurs de validation dans <code class=\"docutils literal notranslate\"><span class=\"pre\">Model.clean()</span></code> pour des champs qui n’apparaissent pas dans un formulaire de modèle (un formulaire peut limiter ses champs à l’aide des attributs <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta.fields</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta.exclude</span></code>). Si vous essayez, vous obtiendrez une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">ValueError</span></code> car l’erreur de validation ne pourra pas être associée au champ absent du formulaire.</p>\n<p>Pour contourner ce problème, il est possible de surcharger <a class=\"reference internal\" href=\"#django.db.models.Model.clean_fields\" title=\"django.db.models.Model.clean_fields\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Model.clean_fields()</span></code></a> car elle reçoit la liste des champs qui sont exclus de la validation. Par exemple</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Article</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">clean_fields</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">exclude</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">clean_fields</span><span class=\"p\">(</span><span class=\"n\">exclude</span><span class=\"o\">=</span><span class=\"n\">exclude</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">status</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;draft&#39;</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pub_date</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"k\">if</span> <span class=\"n\">exclude</span> <span class=\"ow\">and</span> <span class=\"s1\">&#39;status&#39;</span> <span class=\"ow\">in</span> <span class=\"n\">exclude</span><span class=\"p\">:</span>\n                <span class=\"k\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">(</span>\n                    <span class=\"n\">_</span><span class=\"p\">(</span><span class=\"s1\">&#39;Draft entries may not have a publication date.&#39;</span><span class=\"p\">)</span>\n                <span class=\"p\">)</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">({</span>\n                    <span class=\"s1\">&#39;status&#39;</span><span class=\"p\">:</span> <span class=\"n\">_</span><span class=\"p\">(</span>\n                        <span class=\"s1\">&#39;Set status to draft if there is not a &#39;</span>\n                        <span class=\"s1\">&#39;publication date.&#39;</span>\n                     <span class=\"p\">),</span>\n                <span class=\"p\">})</span>\n</code></pre></div>\n</aside>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.validate_unique\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">validate_unique</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">exclude</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.validate_unique\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Cette méthode est semblable à <a class=\"reference internal\" href=\"#django.db.models.Model.clean_fields\" title=\"django.db.models.Model.clean_fields\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">clean_fields()</span></code></a>, mais elle valide toutes les contraintes d’unicité du modèle au lieu des valeurs de champs individuelles. Le paramètre facultatif <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude</span></code> peut être utilisé pour fournir une liste de noms de champs à exclure de la validation. Une exception <a class=\"reference internal\" href=\"/fr/3.1/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ValidationError</span></code></a> est générée pour chaque champ dont la validation échoue.</p>\n<p>Notez que si vous renseignez le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude</span></code> de <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_unique()</span></code>, les contraintes <a class=\"reference internal\" href=\"/fr/3.1/ref/models/options/#django.db.models.Options.unique_together\" title=\"django.db.models.Options.unique_together\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">unique_together</span></code></a> impliquant l’un des champs de la liste ne seront pas contrôlées.</p>\n</section>\n<section id=\"saving-objects\">\n<h2>Enregistrement d’objets<a class=\"heading-anchor\" href=\"#saving-objects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Pour enregistrer un objet dans la base de données, appelez <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code>:</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.save\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">save</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">force_insert</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">force_update</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">DEFAULT_DB_ALIAS</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">update_fields</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.save\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Si vous souhaitez personnaliser le comportement d’enregistrement, vous pouvez surcharger cette méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code>. Voir <a class=\"reference internal\" href=\"/fr/3.1/topics/db/models/#overriding-model-methods\"><span class=\"std std-ref\">Surcharge des méthodes de modèles prédéfinies</span></a> pour plus de détails.</p>\n<p>Le processus d’enregistrement des modèles comporte également certaines subtilités ; voir les sections ci-dessous.</p>\n<section id=\"auto-incrementing-primary-keys\">\n<h3>Incrémentation automatique des clés primaires<a class=\"heading-anchor\" href=\"#auto-incrementing-primary-keys\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si un modèle contient un champ <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.AutoField\" title=\"django.db.models.AutoField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AutoField</span></code></a> – une clé primaire avec incrémentation automatique – la valeur incrémentée automatiquement sera calculée et enregistrée comme attribut de l’objet lors de son premier enregistrement avec <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b2</span> <span class=\"o\">=</span> <span class=\"n\">Blog</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Cheddar Talk&#39;</span><span class=\"p\">,</span> <span class=\"n\">tagline</span><span class=\"o\">=</span><span class=\"s1\">&#39;Thoughts on cheese.&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b2</span><span class=\"o\">.</span><span class=\"n\">id</span>     <span class=\"c1\"># Returns None, because b2 doesn&#39;t have an ID yet.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b2</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b2</span><span class=\"o\">.</span><span class=\"n\">id</span>     <span class=\"c1\"># Returns the ID of your new object.</span>\n</code></pre></div>\n<p>Il n’est pas possible de connaître la valeur future de l’identifiant avant d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code>, car cette valeur est calculée par la base de données, et non par Django.</p>\n<p>Par commodité, chaque modèle possède par défaut un champ <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.AutoField\" title=\"django.db.models.AutoField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AutoField</span></code></a> nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">id</span></code>, sauf dans le cas où vous ajoutez explicitement le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">primary_key=True</span></code> à l’un des champs du modèle. Consultez la documentation de <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.AutoField\" title=\"django.db.models.AutoField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AutoField</span></code></a> pour plus de détails.</p>\n<section id=\"the-pk-property\">\n<h4>La propriété <code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code><a class=\"heading-anchor\" href=\"#the-pk-property\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.pk\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">pk</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Model.pk\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Que vous définissiez vous-même un champ de clé primaire ou que vous laissiez Django s’en charger, chaque modèle possède une propriété nommée <code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code>. Elle se comporte comme un attribut normal du modèle, mais représente en réalité un alias vers l’attribut du modèle qui a la fonction de clé primaire. Vous pouvez lire et définir cette valeur, comme vous le feriez pour tout autre attribut, et l’action s’applique au bon champ du modèle, c’est-à-dire à la clé primaire.</p>\n</section>\n<section id=\"explicitly-specifying-auto-primary-key-values\">\n<h4>Définition explicite des valeurs de clés primaires<a class=\"heading-anchor\" href=\"#explicitly-specifying-auto-primary-key-values\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si un modèle contient un champ <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.AutoField\" title=\"django.db.models.AutoField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AutoField</span></code></a> mais que vous souhaiteriez définir explicitement l’identifiant d’un nouvel objet lors de son enregistrement, définissez-le explicitement avant de l’enregistrer, plutôt que de compter sur l’attribution automatique de l’identifiant :</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=\"n\">b3</span> <span class=\"o\">=</span> <span class=\"n\">Blog</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Cheddar Talk&#39;</span><span class=\"p\">,</span> <span class=\"n\">tagline</span><span class=\"o\">=</span><span class=\"s1\">&#39;Thoughts on cheese.&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b3</span><span class=\"o\">.</span><span class=\"n\">id</span>     <span class=\"c1\"># Returns 3.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b3</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b3</span><span class=\"o\">.</span><span class=\"n\">id</span>     <span class=\"c1\"># Returns 3.</span>\n</code></pre></div>\n<p>Si vous attribuez manuellement des valeurs de clé primaire habituellement automatiques, prenez garde de ne pas utiliser des valeurs déjà existantes ! Si vous créez un nouvel objet avec une valeur de clé primaire explicite qui existe déjà dans la base de données, Django pense que vous modifiez un objet existant, et non que vous en créez un nouveau.</p>\n<p>En reprenant l’exemple du blog <code class=\"docutils literal notranslate\"><span class=\"pre\">'Cheddar</span> <span class=\"pre\">Talk'</span></code> ci-dessus, cet exemple écraserait l’objet existant dans la base de donné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=\"n\">b4</span> <span class=\"o\">=</span> <span class=\"n\">Blog</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Not Cheddar&#39;</span><span class=\"p\">,</span> <span class=\"n\">tagline</span><span class=\"o\">=</span><span class=\"s1\">&#39;Anything but cheese.&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">b4</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>  <span class=\"c1\"># Overrides the previous blog with ID=3!</span>\n</code></pre></div>\n<p>Lisez <a class=\"reference internal\" href=\"#how-django-knows-to-update-vs-insert\">Comment Django distingue UPDATE de INSERT</a> ci-dessous, pour comprendre pourquoi cela se passe ainsi.</p>\n<p>La définition explicite de valeurs de clés primaires est essentiellement utile lors de l’enregistrement d’objets en vrac, lorsque l’on est à peu près certain qu’il n’y aura pas de collision de clés primaires.</p>\n<p>Si vous utilisez PostgreSQL, la séquence associée à la clé primaire pourrait devoir être mise à jour ; voir <a class=\"reference internal\" href=\"/fr/3.1/ref/databases/#manually-specified-autoincrement-pk\"><span class=\"std std-ref\">Indication manuelle des valeurs de clé primaire avec autoincrémentation</span></a>.</p>\n</section>\n</section>\n<section id=\"what-happens-when-you-save\">\n<h3>Que se passe-t-il lors de l’enregistrement ?<a class=\"heading-anchor\" href=\"#what-happens-when-you-save\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lorsque vous enregistrez un objet, Django effectue les étapes suivantes :</p>\n<ol class=\"arabic\">\n<li><p><strong>Émission d’un signal avant enregistrement.</strong> Le signal <a class=\"reference internal\" href=\"/fr/3.1/ref/signals/#django.db.models.signals.pre_save\" title=\"django.db.models.signals.pre_save\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.pre_save</span></code></a> est envoyé, permettant à toute fonction à l’écoute de ce signal d’accomplir une action.</p></li>\n<li><p><strong>Préparation des données.</strong> La méthode <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.Field.pre_save\" title=\"django.db.models.Field.pre_save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">pre_save()</span></code></a> de chaque champ est appelée pour effectuer toute éventuelle modification automatique de données. Par exemple, les champs date/heure surchargent <code class=\"docutils literal notranslate\"><span class=\"pre\">pre_save()</span></code> pour implémenter <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.DateField.auto_now_add\" title=\"django.db.models.DateField.auto_now_add\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">auto_now_add</span></code></a> et <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.DateField.auto_now\" title=\"django.db.models.DateField.auto_now\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">auto_now</span></code></a>.</p></li>\n<li><p><strong>Préparation des données pour la base de données.</strong> La méthode <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.Field.get_db_prep_save\" title=\"django.db.models.Field.get_db_prep_save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_db_prep_save()</span></code></a> de chaque champ doit fournir sa valeur actuelle dans un type de données qui peut être écrit dans la base de données.</p>\n<p>La plupart des champs ne nécessitent aucune préparation de données. Les types de données simples, comme les entiers ou les chaînes de caractères, sont « prêtes à l’écriture » en tant qu’objet Python. Cependant, les types de données plus complexes ont souvent besoin de certaines modifications.</p>\n<p>Par exemple, les champs <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.DateField\" title=\"django.db.models.DateField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DateField</span></code></a> utilisent un objet Python <code class=\"docutils literal notranslate\"><span class=\"pre\">datetime</span></code> pour stocker leurs données. Les bases de données ne peuvent pas stocker d’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">datetime</span></code>, il faut donc que la valeur du champ soit convertie dans une chaîne date au format ISO pour être insérée dans la base de données.</p>\n</li>\n<li><p><strong>Insertion des données dans la base de données.</strong> Les données pré-traitées et préparées sont converties en instruction SQL en vue de leur insertion dans la base de données.</p></li>\n<li><p><strong>Émission d’un signal après enregistrement.</strong> Le signal <a class=\"reference internal\" href=\"/fr/3.1/ref/signals/#django.db.models.signals.post_save\" title=\"django.db.models.signals.post_save\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.post_save</span></code></a> est envoyé, permettant à toute fonction à l’écoute de ce signal d’accomplir une action.</p></li>\n</ol>\n</section>\n<section id=\"how-django-knows-to-update-vs-insert\">\n<h3>Comment Django distingue UPDATE de INSERT<a class=\"heading-anchor\" href=\"#how-django-knows-to-update-vs-insert\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous avez peut-être remarqué que les objets de base de données de Django utilisent la même méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> pour créer ou modifier des objets. La couche d’abstraction de Django évite de devoir différencier les instructions SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code>. Plus concrètement, lors de l’appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> et que l’attribut clé primaire de l’objet ne définit <strong>pas</strong> de valeur <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.Field.default\" title=\"django.db.models.Field.default\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">default</span></code></a>, Django suit l’algorithme suivant :</p>\n<ul class=\"simple\">\n<li><p>Si l’attribut de clé primaire de l’objet est défini à une valeur équivalent à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> (c’est-à-dire une valeur autre que <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> ou que la chaîne vide), Django effectue une instruction <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code> (mise à jour).</p></li>\n<li><p>Si l’attribut de clé primaire de l’objet n’est <em>pas</em> défini où si l’instruction <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code> n’a rien mis à jour (par ex. si la clé primaire est définie à une valeur qui n’existe pas en base de données), Django exécute une requête <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code>.</p></li>\n</ul>\n<p>Si l’attribut clé primaire de l’objet définit une valeur par défaut <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.Field.default\" title=\"django.db.models.Field.default\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">default</span></code></a>, Django exécute une instruction <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code> s’il s’agit d’une instance de modèle existante et que sa clé primaire est définie à une valeur qui existe dans la base de données. Sinon, Django exécute une instruction <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code>.</p>\n<p>Le point délicat ici est de faire attention à ne pas indiquer explicitement de valeur de clé primaire lors de l’enregistrement de nouveaux objets, si vous ne pouvez garantir que cette clé primaire est libre. Pour plus de détails sur cette nuance, consultez <a class=\"reference internal\" href=\"#explicitly-specifying-auto-primary-key-values\">Définition explicite des valeurs de clés primaires</a> ci-dessus et <a class=\"reference internal\" href=\"#forcing-an-insert-or-update\">Contrainte d’insertion ou de mise à jour</a> ci-dessous.</p>\n<p>Jusqu’à Django 1.5, Django faisait un <code class=\"docutils literal notranslate\"><span class=\"pre\">SELECT</span></code> lorsque l’attribut de clé primaire était défini. Si le <code class=\"docutils literal notranslate\"><span class=\"pre\">SELECT</span></code> trouvait un objet, Django effectuait ensuite un <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code>, sinon il procédait à un <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code>. Cet ancien algorithme produisait une requête supplémentaire dans le cas <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code>. Il peut arriver dans certains cas que la base de données ne signale pas qu’une ligne a été mise à jour même quand il existe une ligne de base de données correspondant à la clé primaire de l’objet. Un exemple est le déclencheur <code class=\"docutils literal notranslate\"><span class=\"pre\">ON</span> <span class=\"pre\">UPDATE</span></code> de PostgreSQL qui renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">NULL</span></code>. Dans de tels cas, il est possible de revenir à l’algorithme précédent en définissant l’option <a class=\"reference internal\" href=\"/fr/3.1/ref/models/options/#django.db.models.Options.select_on_save\" title=\"django.db.models.Options.select_on_save\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">select_on_save</span></code></a> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>.</p>\n<aside class=\"version-note version-changed\" data-version=\"3.0\">\n<p class=\"version-note-title\">Changed in Django 3.0</p><p><code class=\"docutils literal notranslate\"><span class=\"pre\">Model.save()</span></code> n’essaie plus de trouver un enregistrement de base de données lors de l’enregistrement d’une nouvelle instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Model</span></code> et qu’une valeur par défaut est définie pour la clé primaire ; dans ce cas, il procède toujours à un <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code>.</p>\n</aside>\n<section id=\"forcing-an-insert-or-update\">\n<span id=\"ref-models-force-insert\"></span><h4>Contrainte d’insertion ou de mise à jour<a class=\"heading-anchor\" href=\"#forcing-an-insert-or-update\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Dans de rares circonstances, il est nécessaire de pouvoir forcer la méthode <a class=\"reference internal\" href=\"#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a> à recourir à une instruction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code> au lieu d’une instruction <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code>. Ou l’inverse : mettre à jour si possible, mais ne pas insérer un nouvel enregistrement. Dans ces situations, il est possible de fournir les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">force_insert=True</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">force_update=True</span></code> à la méthode <a class=\"reference internal\" href=\"#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a>. Il est faux de fournir les deux paramètres simultanément : il est impossible d’insérer <em>et</em> de mettre à jour en même temps !</p>\n<p>L’usage de ces paramètres est très rare. Django effectue presque toujours le bon choix et en surchargeant le comportement habituel, des erreurs difficiles à détecter peuvent survenir. Cette fonctionnalité est réservée aux experts.</p>\n<p>L’utilisation de <code class=\"docutils literal notranslate\"><span class=\"pre\">update_fields</span></code> force une mise à jour de la même façon que <code class=\"docutils literal notranslate\"><span class=\"pre\">force_update</span></code>.</p>\n</section>\n</section>\n<section id=\"updating-attributes-based-on-existing-fields\">\n<span id=\"ref-models-field-updates-using-f-expressions\"></span><h3>Mise à jour d’attributs basés sur des champs existants<a class=\"heading-anchor\" href=\"#updating-attributes-based-on-existing-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il est parfois nécessaire d’effectuer une tâche arithmétique simple sur un champ, comme l’incrémentation ou la décrémentation de la valeur actuelle. Une façon de faire cela serait d’effectuer l’arithmétique en Python 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=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">product</span> <span class=\"o\">=</span> <span class=\"n\">Product</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Venezuelan Beaver Cheese&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">product</span><span class=\"o\">.</span><span class=\"n\">number_sold</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">product</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Si la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">number_sold</span></code> existante dans la base de données est 10, c’est la valeur 11 qui sera écrite comme nouvelle valeur en base de données.</p>\n<p>Ce processus peut être solidifié, <a class=\"reference internal\" href=\"/fr/3.1/ref/models/expressions/#avoiding-race-conditions-using-f\"><span class=\"std std-ref\">évitant un conflit de concurrence</span></a>, et rendu légèrement plus rapide en exprimant la mise à jour relativement à la valeur existante plutôt qu’en attribuant explicitement une nouvelle valeur. Django fournit des <a class=\"reference internal\" href=\"/fr/3.1/ref/models/expressions/#django.db.models.F\" title=\"django.db.models.F\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">expressions</span> <span class=\"pre\">F</span></code></a> pour parvenir à ce genre de mise à jour relative. En employant des <a class=\"reference internal\" href=\"/fr/3.1/ref/models/expressions/#django.db.models.F\" title=\"django.db.models.F\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">expressions</span> <span class=\"pre\">F</span></code></a>, l’exemple précédent est formulé ainsi :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">F</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">product</span> <span class=\"o\">=</span> <span class=\"n\">Product</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Venezuelan Beaver Cheese&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">product</span><span class=\"o\">.</span><span class=\"n\">number_sold</span> <span class=\"o\">=</span> <span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;number_sold&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">product</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Pour plus de détails, consultez la documentation sur les <a class=\"reference internal\" href=\"/fr/3.1/ref/models/expressions/#django.db.models.F\" title=\"django.db.models.F\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">expressions</span> <span class=\"pre\">F</span></code></a> et leur <a class=\"reference internal\" href=\"/fr/3.1/topics/db/queries/#topics-db-queries-update\"><span class=\"std std-ref\">emploi dans les requêtes de mise à jour</span></a>.</p>\n</section>\n<section id=\"specifying-which-fields-to-save\">\n<h3>Indication des champs à enregistrer<a class=\"heading-anchor\" href=\"#specifying-which-fields-to-save\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>En transmettant une liste de noms de champs dans le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">update_fields</span></code> de <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code>, seuls les champs figurant dans cette liste sont mis à jour. Cela peut être judicieux lorsque un petit sous-ensemble des champs d’un objet doivent être mis à jour. Un léger gain de performances peut être espéré en évitant de mettre à jour tous les champs du modèle en base de données. 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=\"n\">product</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Name changed again&#39;</span>\n<span class=\"n\">product</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">update_fields</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">update_fields</span></code> argument can be any iterable containing strings. An\nempty <code class=\"docutils literal notranslate\"><span class=\"pre\">update_fields</span></code> iterable will skip the save. A value of <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> will\nperform an update on all fields.</p>\n<p>L’utilisation de <code class=\"docutils literal notranslate\"><span class=\"pre\">update_fields</span></code> force une mise à jour.</p>\n<p>Lors de l’enregistrement d’un modèle obtenu par chargement différé de modèle (<a class=\"reference internal\" href=\"/fr/3.1/ref/models/querysets/#django.db.models.query.QuerySet.only\" title=\"django.db.models.query.QuerySet.only\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">only()</span></code></a> ou <a class=\"reference internal\" href=\"/fr/3.1/ref/models/querysets/#django.db.models.query.QuerySet.defer\" title=\"django.db.models.query.QuerySet.defer\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">defer()</span></code></a>), seuls les champs chargés à partir de la base de données sont mis à jour. Dans ce cas, l’effet est semblable à un <code class=\"docutils literal notranslate\"><span class=\"pre\">update_fields</span></code> automatique. Si vous attribuez ou que vous modifiez l’une des valeurs de champ différé, le champ est ajouté aux champs à mettre à jour.</p>\n</section>\n</section>\n<section id=\"deleting-objects\">\n<h2>Suppression d’objets<a class=\"heading-anchor\" href=\"#deleting-objects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.delete\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">delete</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">DEFAULT_DB_ALIAS</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">keep_parents</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.delete\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Effectue une instruction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">DELETE</span></code> pour l’objet. Cela ne fait que supprimer l’objet dans la base de données ; l’instance Python existe toujours et ses champs contiennent encore les données. Cette méthode renvoie le nombre d’objets supprimés ainsi qu’un dictionnaire avec le nombre de suppressions par type d’objet.</p>\n<p>Pour plus de détails, y compris sur la suppression d’objets en vrac, consultez <a class=\"reference internal\" href=\"/fr/3.1/topics/db/queries/#topics-db-queries-delete\"><span class=\"std std-ref\">Suppression d’objets</span></a>.</p>\n<p>Si vous avez besoin d’un comportement de suppression personnalisé, vous pouvez surcharger la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">delete()</span></code>. Voir <a class=\"reference internal\" href=\"/fr/3.1/topics/db/models/#overriding-model-methods\"><span class=\"std std-ref\">Surcharge des méthodes de modèles prédéfinies</span></a> pour plus de détails.</p>\n<p>Il peut arriver parfois qu’avec l”<a class=\"reference internal\" href=\"/fr/3.1/topics/db/models/#multi-table-inheritance\"><span class=\"std std-ref\">héritage multi-table</span></a>, on ne veuille supprimer que les données d’un modèle enfant. En indiquant <code class=\"docutils literal notranslate\"><span class=\"pre\">keep_parents=True</span></code>, les données du modèle parent sont conservées.</p>\n</section>\n<section id=\"pickling-objects\">\n<h2>Sérialisation « pickle » d’objets<a class=\"heading-anchor\" href=\"#pickling-objects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Lorsqu’on utilise <a class=\"reference external\" href=\"https://docs.python.org/3/library/pickle.html#module-pickle\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">pickle</span></code></a> sur un modèle, son état actuel est sérialisé. Lors de la désérialisation, il contiendra l’instance de modèle telle qu’elle était au moment de sa sérialisation, et non pas dans l’état actuel des données de la base de données.</p>\n<aside class=\"admonition-you-can-t-share-pickles-between-versions admonition\">\n<p class=\"admonition-title\">Il  n’est pas possible de partager des sérialisations « pickle » entre différentes versions</p>\n<p>Des sérialisations « pickle » de modèles ne sont valables que pour la version de Django utilisée pour les générer. Si vous produisez du contenu « pickle » avec une version N de Django, il n’y a aucune garantie que ce contenu soit lisible par une version N+1 de Django. La sérialisation « pickle » ne doit pas être utilisée dans le cadre d’une stratégie d’archivage à long terme.</p>\n<p>Comme des erreurs de compatibilité de pickle peuvent être difficiles à diagnostiquer, comme par exemple des objets silencieusement corrompus, un avertissement <code class=\"docutils literal notranslate\"><span class=\"pre\">RuntimeWarning</span></code> est produit si vous essayer de désérialiser un modèle dans une version de Django différente de celle qui a été utilisée pour la sérialisation.</p>\n</aside>\n</section>\n<section id=\"other-model-instance-methods\">\n<span id=\"model-instance-methods\"></span><h2>Autres méthodes d’instance de modèle<a class=\"heading-anchor\" href=\"#other-model-instance-methods\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Quelques méthodes d’objet ont un rôle spécifique.</p>\n<section id=\"str\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">__str__()</span></code><a class=\"heading-anchor\" href=\"#str\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.__str__\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">__str__</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.__str__\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__()</span></code> est appelée chaque fois que <code class=\"docutils literal notranslate\"><span class=\"pre\">str()</span></code> est appelée sur un objet. Django utilise <code class=\"docutils literal notranslate\"><span class=\"pre\">str(obj)</span></code> à plusieurs occasions. Plus particulièrement, pour afficher un objet dans le site d’administration de Django et pour produire la valeur insérée dans un gabarit lors de l’affichage d’un objet. Il est donc important de toujours renvoyer une représentation utile et intelligible du modèle en réponse à la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__()</span></code>.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"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><span class=\"n\">first_name</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">last_name</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"eq\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">__eq__()</span></code><a class=\"heading-anchor\" href=\"#eq\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.__eq__\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">__eq__</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.__eq__\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>La méthode d’égalité est définie telle que des instances avec la même valeur de clé primaire et la même classe concrète sont considérées comme égales, sauf pour les instances dont la valeur de clé primaire est <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> qui ne sont toujours égales qu’à elles-mêmes. Pour les modèles mandataires, la classe concrète est définie comme le premier parent non mandataire du modèle ; pour tous les autres modèles, c’est simplement la classe du modèle.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"nb\">id</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">AutoField</span><span class=\"p\">(</span><span class=\"n\">primary_key</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyProxyModel</span><span class=\"p\">(</span><span class=\"n\">MyModel</span><span class=\"p\">):</span>\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">proxy</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MultitableInherited</span><span class=\"p\">(</span><span class=\"n\">MyModel</span><span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n\n<span class=\"c1\"># Primary keys compared</span>\n<span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"c1\"># Primary keys are None</span>\n<span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>\n<span class=\"c1\"># Same instance</span>\n<span class=\"n\">instance</span> <span class=\"o\">=</span> <span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>\n<span class=\"n\">instance</span> <span class=\"o\">==</span> <span class=\"n\">instance</span>\n<span class=\"c1\"># Proxy model</span>\n<span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"n\">MyProxyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"c1\"># Multi-table inheritance</span>\n<span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"n\">MultitableInherited</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"hash\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">__hash__()</span></code><a class=\"heading-anchor\" href=\"#hash\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.__hash__\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">__hash__</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.__hash__\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__hash__</span></code> est basée sur la valeur de clé primaire de l’instance. Il s’agit en pratique de <code class=\"docutils literal notranslate\"><span class=\"pre\">hash(obj.pk)</span></code>. Si l’instance ne possède pas de valeur de clé primaire, une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">TypeError</span></code> est générée (sinon la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__hash__()</span></code> renverrait une valeur différente avant et après l’enregistrement de l’instance, alors que la modification de la valeur <a class=\"reference external\" href=\"https://docs.python.org/3/reference/datamodel.html#object.__hash__\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">__hash__()</span></code></a> d’une instance est interdit en Python).</p>\n</section>\n<section id=\"get-absolute-url\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code><a class=\"heading-anchor\" href=\"#get-absolute-url\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.get_absolute_url\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_absolute_url</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.get_absolute_url\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Définissez une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code> pour indiquer à Django la façon de calculer l’URL canonique d’un objet. Pour l’appelant, cette méthode doit renvoyer une chaîne pouvant être utilisée pour se référer à un objet par HTTP.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_absolute_url</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"s2\">&quot;/people/</span><span class=\"si\">%i</span><span class=\"s2\">/&quot;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">id</span>\n</code></pre></div>\n<p>Bien que ce code soit correct et simple, ce n’est peut-être pas la manière la plus portable d’écrire ce genre de méthode. La fonction <a class=\"reference internal\" href=\"/fr/3.1/ref/urlresolvers/#django.urls.reverse\" title=\"django.urls.reverse\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">reverse()</span></code></a> est habituellement la meilleure approche.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_absolute_url</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">reverse</span>\n    <span class=\"k\">return</span> <span class=\"n\">reverse</span><span class=\"p\">(</span><span class=\"s1\">&#39;people.views.details&#39;</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">id</span><span class=\"p\">)])</span>\n</code></pre></div>\n<p>Un endroit où Django utilise <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code> est l’application d’administration. Si un objet définit cette méthode, la page d’édition d’objet présentera un lien « Voir sur le site » qui vous amène directement sur la page d’affichage public de l’objet, telle qu’indiquée par <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code>.</p>\n<p>De même, certaines autres parties de Django, comme le <a class=\"reference internal\" href=\"/fr/3.1/ref/contrib/syndication/\"><span class=\"doc\">système de flux de syndication</span></a>, utilisent <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code> lorsqu’elle est définie. Si le fait de posséder une URL unique pour chaque instance de modèle fait sens, vous devriez définir <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code>.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Vous devriez éviter de construire des URL à partir de contenu utilisateur non validé, afin de réduire les possibilités de corruption de lien ou de redirection :</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\">def</span><span class=\"w\"> </span><span class=\"nf\">get_absolute_url</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"s1\">&#39;/</span><span class=\"si\">%s</span><span class=\"s1\">/&#39;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span>\n</code></pre></div>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">self.name</span></code> est <code class=\"docutils literal notranslate\"><span class=\"pre\">'/example.com'</span></code>, ceci renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">'//example.com/'</span></code> qui est aussi un protocole valide d’URL relative, mais ne correspond pas à <code class=\"docutils literal notranslate\"><span class=\"pre\">'/%2Fexample.com/'</span></code> qui était attendu.</p>\n</aside>\n<p>L’utilisation de <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code> dans les gabarits est reconnu comme une bonne pratique, au lieu de figer les URL des objets à des chaînes fixes. Par exemple, ce code de gabarit est mauvais :</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"cm\">&lt;!-- BAD template code. Avoid! --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;/people/</span><span class=\"cp\">{{</span> <span class=\"nv\">object.id</span> <span class=\"cp\">}}</span><span class=\"s\">/&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">object.name</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Ce code de gabarit est bien meilleur :</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">object.get_absolute_url</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">object.name</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Ici, la logique est que si vous modifiez la structure des URL de vos objets, même s’il ne s’agissait que d’une petite correction orthographique, il n’est pas acceptable de devoir rechercher tous les endroits où l’URL en question pourrait être écrite. On la définit une seule fois dans <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code> et tous les autres endroits du code peuvent alors référencer cette méthode.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>La chaîne renvoyée par <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code> ne <strong>doit</strong> contenir que des caractères ASCII (exigence de la spécification d’URI <span class=\"target\" id=\"index-2\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc2396.html#section-2\"><strong>RFC 2396 Section 2</strong></a>) et être codée en syntaxe URL, si nécessaire.</p>\n<p>Le code et les gabarits faisant appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span></code> doivent pouvoir utiliser le résultat directement sans plus de traitement. Il peut être utile d’appeler la fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.encoding.iri_to_uri()</span></code> pour contribuer à cet objectif si vous utilisez des caractères en dehors de la plage ASCII.</p>\n</aside>\n</section>\n</section>\n<section id=\"extra-instance-methods\">\n<h2>Méthodes d’instances supplémentaires<a class=\"heading-anchor\" href=\"#extra-instance-methods\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>En plus de <a class=\"reference internal\" href=\"#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a> et <a class=\"reference internal\" href=\"#django.db.models.Model.delete\" title=\"django.db.models.Model.delete\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">delete()</span></code></a>, un objet de modèle peut posséder certaines des méthodes suivantes :</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.get_FOO_display\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_FOO_display</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.get_FOO_display\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Pour chaque champ ayant le paramètre <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.Field.choices\" title=\"django.db.models.Field.choices\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">choices</span></code></a>, l’objet dispose d’une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_FOO_display()</span></code>, où <code class=\"docutils literal notranslate\"><span class=\"pre\">FOO</span></code> est le nom du champ. Cette méthode renvoie une valeur « intelligible » pour ce champ.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">SHIRT_SIZES</span> <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    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">60</span><span class=\"p\">)</span>\n    <span class=\"n\">shirt_size</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">choices</span><span class=\"o\">=</span><span class=\"n\">SHIRT_SIZES</span><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><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;Fred Flintstone&quot;</span><span class=\"p\">,</span> <span class=\"n\">shirt_size</span><span class=\"o\">=</span><span class=\"s2\">&quot;L&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">shirt_size</span>\n<span class=\"go\">&#39;L&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">get_shirt_size_display</span><span class=\"p\">()</span>\n<span class=\"go\">&#39;Large&#39;</span>\n</code></pre></div>\n<aside class=\"version-note version-changed\" data-version=\"3.1\">\n<p class=\"version-note-title\">Changed in Django 3.1</p><p>La prise en charge des champs <a class=\"reference internal\" href=\"/fr/3.1/ref/contrib/postgres/fields/#django.contrib.postgres.fields.ArrayField\" title=\"django.contrib.postgres.fields.ArrayField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ArrayField</span></code></a> et <a class=\"reference internal\" href=\"/fr/3.1/ref/contrib/postgres/fields/#django.contrib.postgres.fields.RangeField\" title=\"django.contrib.postgres.fields.RangeField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RangeField</span></code></a> a été ajoutée.</p>\n</aside>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.get_next_by_FOO\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_next_by_FOO</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.get_next_by_FOO\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model.get_previous_by_FOO\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_previous_by_FOO</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Model.get_previous_by_FOO\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Pour chaque champ <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.DateField\" title=\"django.db.models.DateField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DateField</span></code></a> et <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DateTimeField</span></code></a> ne possédant pas le paramètre <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.Field.null\" title=\"django.db.models.Field.null\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">null=True</span></code></a>, l’objet disposera de méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">get_next_by_FOO()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">get_previous_by_FOO()</span></code>, où <code class=\"docutils literal notranslate\"><span class=\"pre\">FOO</span></code> est le nom du champ. Celles-ci renvoient respectivement l’objet suivant et l’objet précédent en fonction du champ date, générant une exception <a class=\"reference internal\" href=\"/fr/3.1/ref/models/class/#django.db.models.Model.DoesNotExist\" title=\"django.db.models.Model.DoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">DoesNotExist</span></code></a> le cas échéant.</p>\n<p>Ces deux méthodes effectuent leurs requêtes en utilisant le gestionnaire par défaut du modèle. Si vous avez besoin d’émuler le filtrage d’un gestionnaire personnalisé ou que vous vouliez effectuer un filtrage personnalisé unique, ces deux méthodes acceptent aussi des paramètres nommés facultatifs qui devraient correspondre au format décrit dans <a class=\"reference internal\" href=\"/fr/3.1/ref/models/querysets/#field-lookups\"><span class=\"std std-ref\">Recherches dans les champs</span></a>.</p>\n<p>Notez qu’en cas de valeurs datées identiques, ces méthodes emploient la clé primaire pour déterminer l’objet choisi. Cela permet de garantir qu’aucun objet ne sera omis ou dupliqué. Cela signifie également qu’il n’est pas possible d’utiliser ces méthodes pour des objets non enregistrés.</p>\n<aside class=\"admonition-overriding-extra-instance-methods admonition\">\n<p class=\"admonition-title\">Surcharge de méthodes d’instance supplémentaires</p>\n<p>Dans la plupart des cas, la surcharge ou l’héritage des méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">get_FOO_display()</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">get_next_by_FOO()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">get_previous_by_FOO()</span></code> fonctionne comme attendu. Toutefois, comme celles-ci sont ajoutées par la métaclasse, il n’est en pratique pas possible de considérer toutes les structures d’héritage possibles. Dans les cas plus complexes, vous devriez surcharger <code class=\"docutils literal notranslate\"><span class=\"pre\">Field.contribute_to_class()</span></code> afin de définir les méthodes dont vous avez besoin.</p>\n</aside>\n</section>\n<section id=\"other-attributes\">\n<h2>Autres attributs<a class=\"heading-anchor\" href=\"#other-attributes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"state\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">_state</span></code><a class=\"heading-anchor\" href=\"#state\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Model._state\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Model.</span></span><span class=\"sig-name descname\"><span class=\"pre\">_state</span></span><a class=\"heading-anchor\" href=\"#django.db.models.Model._state\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>L’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">_state</span></code> fait référence à un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelState</span></code> qui suit le cycle de vie de l’instance du modèle.</p>\n<p>L’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelState</span></code> a deux attributs : <code class=\"docutils literal notranslate\"><span class=\"pre\">adding</span></code>, un drapeau qui vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si le modèle n’a pas été enregistré en base de données, et <code class=\"docutils literal notranslate\"><span class=\"pre\">db</span></code>, une chaîne faisant référence à l’alias de base de données depuis laquelle l’instance a été chargée ou enregistrée.</p>\n<p>Les nouvelles instances créées ont <code class=\"docutils literal notranslate\"><span class=\"pre\">adding=True</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">db=None</span></code>, car elles sont sur le point d’être enregistrées. Les instances récupérées depuis un <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> auront <code class=\"docutils literal notranslate\"><span class=\"pre\">adding=False</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">db</span></code>  défini à l’alias de la base de données associée.</p>\n</dd></dl>\n\n</section>\n</section>","rootId":"model-instance-reference","toc":[{"title":"Création d’objets","anchor":"creating-objects","children":[{"title":"Personnalisation du chargement des modèles","anchor":"customizing-model-loading","children":[]}]},{"title":"Actualisation des objets à partir de la base de données","anchor":"refreshing-objects-from-database","children":[]},{"title":"Validation d’objets","anchor":"validating-objects","children":[]},{"title":"Enregistrement d’objets","anchor":"saving-objects","children":[{"title":"Incrémentation automatique des clés primaires","anchor":"auto-incrementing-primary-keys","children":[{"title":"La propriété pk","anchor":"the-pk-property","children":[]},{"title":"Définition explicite des valeurs de clés primaires","anchor":"explicitly-specifying-auto-primary-key-values","children":[]}]},{"title":"Que se passe-t-il lors de l’enregistrement ?","anchor":"what-happens-when-you-save","children":[]},{"title":"Comment Django distingue UPDATE de INSERT","anchor":"how-django-knows-to-update-vs-insert","children":[{"title":"Contrainte d’insertion ou de mise à jour","anchor":"forcing-an-insert-or-update","children":[]}]},{"title":"Mise à jour d’attributs basés sur des champs existants","anchor":"updating-attributes-based-on-existing-fields","children":[]},{"title":"Indication des champs à enregistrer","anchor":"specifying-which-fields-to-save","children":[]}]},{"title":"Suppression d’objets","anchor":"deleting-objects","children":[]},{"title":"Sérialisation « pickle » d’objets","anchor":"pickling-objects","children":[]},{"title":"Autres méthodes d’instance de modèle","anchor":"other-model-instance-methods","children":[{"title":"__str__()","anchor":"str","children":[]},{"title":"__eq__()","anchor":"eq","children":[]},{"title":"__hash__()","anchor":"hash","children":[]},{"title":"get_absolute_url()","anchor":"get-absolute-url","children":[]}]},{"title":"Méthodes d’instances supplémentaires","anchor":"extra-instance-methods","children":[]},{"title":"Autres attributs","anchor":"other-attributes","children":[{"title":"_state","anchor":"state","children":[]}]}],"breadcrumbs":[{"docname":"ref/index","title":"Référence de l’API","url":"/fr/3.1/ref/"},{"docname":"ref/models/index","title":"Modèles","url":"/fr/3.1/ref/models/"}],"prev":{"docname":"ref/models/options","title":"Options Meta des modèles","url":"/fr/3.1/ref/models/options/"},"next":{"docname":"ref/models/querysets","title":"Référence de l’API QuerySet","url":"/fr/3.1/ref/models/querysets/"},"formats":{"html":"/fr/3.1/ref/models/instances/","markdown":"/fr/3.1/ref/models/instances.md","json":"/fr/3.1/ref/models/instances.json"},"source":"https://github.com/django/django/blob/stable/3.1.x/docs/ref/models/instances.txt","official":"https://docs.djangoproject.com/fr/3.1/ref/models/instances/","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","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}