{"title":"Migrations","version":"3.0","locale":"fr","docname":"topics/migrations","url":"/fr/3.0/topics/migrations/","canonical":"https://djangodocs.dev/fr/3.0/topics/migrations/","summary":"Les migrations sont la manière par laquelle Django propage des modifications que vous apportez à des modèles (ajout d’un champ, suppression d’un modèle, etc.) dans…","html":"<span id=\"migrations\"></span><h1>Migrations<a class=\"heading-anchor\" href=\"#module-django.db.migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Les migrations sont la manière par laquelle Django propage des modifications que vous apportez à des modèles (ajout d’un champ, suppression d’un modèle, etc.) dans un schéma de base de données. Elles sont conçues pour être quasiment automatiques, mais vous aurez besoin de savoir quand créer les migrations, quand les exécuter, et les problèmes courants que vous pourriez rencontrer.</p>\n<section id=\"the-commands\">\n<h2>Les commandes<a class=\"heading-anchor\" href=\"#the-commands\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Il y a plusieurs commandes utiles pour interagir avec les migrations et manipuler le schéma de base de données avec Django :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a>, qui est responsable de l’exécution et de l’annulation des migrations.</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a>, qui est responsable de la création de nouvelles migrations en fonction des modifications que vous avez apportées aux modèles.</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-sqlmigrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">sqlmigrate</span></code></a>, qui affiche les instructions SQL correspondant à une migration.</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-showmigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">showmigrations</span></code></a>, qui affiche la liste des migrations d’un projet ainsi que leur état.</p></li>\n</ul>\n<p>Vous devez imaginer les migrations comme un système de contrôle de versions pour un schéma de base de données. <code class=\"docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code> se charge de regrouper vos changements de modèle dans des fichiers de migration individuels - comme des commits - et <code class=\"docutils literal notranslate\"><span class=\"pre\">migrate</span></code> est chargé d’appliquer les changements à la base de données.</p>\n<p>Les fichiers de migration pour chaque application sont stockés dans un répertoire « migrations » à l’intérieur de l’application, et sont conçus pour faire partie du code source et de la distribution de cette application. Les migrations sont créées une fois sur votre machine de développement, puis exécutées telles quelles sur les machines de vos collègues, les machines de tests, et finalement sur les machines de production.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Pour chaque application, il est possible de redéfinir le nom du paquet qui contient les migrations en utilisant le réglage <a class=\"reference internal\" href=\"/fr/3.0/ref/settings/#std-setting-MIGRATION_MODULES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIGRATION_MODULES</span></code></a>.</p>\n</aside>\n<p>Les migrations se déroulent toujours de la même manière lorsqu’elles sont appliquées sur un même ensemble de données et leurs résultats sont constants et répétables, ce qui signifie que ce que vous voyez dans le développement et les machines de test correspondra exactement à ce qui va se passer en production si les conditions d’exécution sont identiques.</p>\n<p>Django crée des migrations pour tout changement dans les modèles ou les champs, même pour des options qui n’affectent pas la base de données, car pour lui la seule manière de reconstruire un champ correctement est d’avoir accès à l’historique de toutes les modifications ; vous pourriez avoir besoin de ces options lors de migrations de données ultérieures (par exemple, si vous avez défini des règles de validation particulières).</p>\n</section>\n<section id=\"backend-support\">\n<h2>Bases de données prises en charge<a class=\"heading-anchor\" href=\"#backend-support\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les migrations sont prises en charge sur tous les moteurs de bases de données livrées avec Django, ainsi que les bases de données tierces si elles prennent en charge les modifications de schéma (effectuées par l’intermédiaire de la classe <a class=\"reference internal\" href=\"/fr/3.0/ref/schema-editor/\"><span class=\"doc\">SchemaEditor</span></a>).</p>\n<p>Toutefois, certaines bases de données ont plus de fonctionnalités que d’autres quand il s’agit de migrations de schéma ; un certain nombre de mises en garde sont rapportées ci-dessous.</p>\n<section id=\"postgresql\">\n<h3>PostgreSQL<a class=\"heading-anchor\" href=\"#postgresql\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Parmi ces bases de données, PostgreSQL est celle disposant du plus de capacités en terme de prise en charge de schéma.</p>\n<p>La seule restriction est qu’avant PostgreSQL 11, l’ajout de colonnes avec des valeurs par défaut provoque une réécriture complète de la table, dans un temps proportionnel à sa taille. Pour cette raison, il est recommandé de toujours créer de nouvelles colonnes avec <code class=\"docutils literal notranslate\"><span class=\"pre\">null=True</span></code>, car de cette façon elles seront ajoutées immédiatement.</p>\n</section>\n<section id=\"mysql\">\n<h3>MySQL<a class=\"heading-anchor\" href=\"#mysql\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>MySQL ne crée pas de transactions pour les opérations de modification de schéma, ce qui signifie que si une migration ne parvient pas à s’appliquer, vous devrez défaire manuellement les modifications pour essayer de nouveau (il est impossible de revenir à un point de sauvegarde antérieur).</p>\n<p>En outre, MySQL réécrit entièrement les tables pour presque toutes les opérations de schéma et a généralement besoin d’un temps d’exécution proportionnel au nombre de lignes des tables pour ajouter ou supprimer des colonnes. Sur une machine un peu lente, cela peut prendre plus d’une minute par million de lignes ; l’ajout de quelques colonnes à une table de quelques millions d’entrées pourrait bloquer votre site pendant plus de dix minutes.</p>\n<p>Enfin, MySQL a des tailles limites relativement petites pour la longueur des noms de colonnes, tables et index, ainsi qu’une limite sur la taille combinée de toutes les colonnes qu’un index recouvre. Cela signifie que des index qui sont possibles sur d’autres bases de données ne pourront pas toujours être créés avec MySQL.</p>\n</section>\n<section id=\"sqlite\">\n<h3>SQLite<a class=\"heading-anchor\" href=\"#sqlite\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>SQLite ne gère nativement que très peu d’opérations de modifications de schéma, Django tente donc de les émuler par :</p>\n<ul class=\"simple\">\n<li><p>La création d’une nouvelle table pour le nouveau schéma</p></li>\n<li><p>La copie des données de l’une à l’autre</p></li>\n<li><p>La suppression de l’ancienne table</p></li>\n<li><p>Le renommage de la nouvelle table avec le nom de l’ancienne table</p></li>\n</ul>\n<p>Ce processus fonctionne généralement bien, mais il peut être lent et comporter des anomalies. Il n’est pas recommandé d’utiliser et de faire migrer SQLite dans un environnement de production, sauf si vous êtes pleinement conscient des risques et des limites ; la prise en charge de Django de cette fonctionnalité est conçue pour permettre aux développeurs d’utiliser SQLite sur leurs machines en local pour développer des projets Django moins complexes sans avoir besoin d’une base de données complète.</p>\n</section>\n</section>\n<section id=\"workflow\">\n<h2>Procédures<a class=\"heading-anchor\" href=\"#workflow\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django peut créer les migrations à votre place. Modifiez vos modèles - par exemple en ajoutant un champ ou en supprimant un modèle - puis exécutez <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>$ python manage.py makemigrations\nMigrations for &#39;books&#39;:\n  books/migrations/0003_auto.py:\n    - Alter field author on book\n</code></pre></div>\n<p>Les modèles sont analysés et comparés aux versions actuellement contenues dans les fichiers de migration. Puis, un nouveau jeu de migrations est rédigé. Il est chaudement conseillé de lire le résultat produit pour voir ce que <code class=\"docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code> a détecté comme changements. Cette commande n’est pas parfaite, et pour des changements complexes, il se peut qu’elle n’ait pas détecté ce que vous attendiez.</p>\n<p>Lorsque les nouveaux fichiers de migration sont créés, on peut les appliquer à la base de données pour s’assurer qu’ils fonctionnent correctement :</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>$ python manage.py migrate\nOperations to perform:\n  Apply all migrations: books\nRunning migrations:\n  Rendering model states... DONE\n  Applying books.0003_auto... OK\n</code></pre></div>\n<p>Quand la migration a été appliquée, ajoutez la migration et les modifications des modèles dans votre système de gestion de versions par un seul « commit » ; de cette façon, lorsque d’autres développeurs (ou votre serveur de production) obtiennent le nouveau code, ils reçoivent en même temps les modifications des modèles et la migration qui leur correspond.</p>\n<p>Si vous souhaitez attribuer un nom éloquent à une migration au lieu d’un nom généré automatiquement, vous pouvez utilisez l’option <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#cmdoption-makemigrations-name\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">makemigrations</span> <span class=\"pre\">--name</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>$ python manage.py makemigrations --name changed_my_model your_app_label\n</code></pre></div>\n<section id=\"version-control\">\n<h3>Contrôle de versions<a class=\"heading-anchor\" href=\"#version-control\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Comme les migrations sont stockées dans le système de gestion de versions, il peut arriver de temps à autre qu’un autre développeur enregistre une migration pour la même application en même temps que vous, ce qui aboutit à deux migrations préfixées du même numéro.</p>\n<p>Soyez sans crainte, les numéros servent uniquement comme référence pour les développeurs, Django exige seulement que chaque migration soit nommée différemment. Les migrations définissent dans leur fichier les autres migrations dont elles dépendent, y compris les migrations précédentes de la même application, il est donc possible de détecter lorsqu’il y a deux nouvelles migrations pour la même application sans préférence d’ordre.</p>\n<p>Lorsque ceci se produit, Django vous pose la question avec plusieurs options. S’il pense que c’est sans risque, il offre de fusionner automatiquement les deux migrations pour vous. Dans le cas contraire, il vous faudra modifier vous-même les migrations, mais ce n’est pas une opération difficile et elle est expliquée plus en détails dans <a class=\"reference internal\" href=\"#migration-files\"><span class=\"std std-ref\">Fichiers de migrations</span></a> ci-dessous.</p>\n</section>\n</section>\n<section id=\"dependencies\">\n<h2>Dépendances<a class=\"heading-anchor\" href=\"#dependencies\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Bien que les migrations sont spécifiques à chaque application, les tables et les relations déterminées par les modèles sont trop complexes pour être créées pour une application à la fois. Lorsque vous créez une migration qui nécessite qu’une autre opération soit exécutée, par exemple l’ajout d’une clé <code class=\"docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code> de l’application <code class=\"docutils literal notranslate\"><span class=\"pre\">livres</span></code> vers l’application <code class=\"docutils literal notranslate\"><span class=\"pre\">auteurs</span></code>, la migration résultante contiendra une dépendance sur une migration dans <code class=\"docutils literal notranslate\"><span class=\"pre\">auteurs</span></code>.</p>\n<p>Cela signifie que quand vous exécutez les migrations, la migration de <code class=\"docutils literal notranslate\"><span class=\"pre\">auteurs</span></code> s’exécute en premier et crée la table référencée par la clé étrangère, puis la migration qui crée la colonne <code class=\"docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code> peut s’exécuter et créer la contrainte. Si cela ne se faisait pas ainsi, la migration essaierait de créer une colonne <code class=\"docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code> sans que la table référencée n’existe et la base de données signalerait une erreur.</p>\n<p>Ce comportement de dépendances affecte la majorité des opérations de migration qui sont limitées à une seule application. La restriction à une seule application (que ce soit pour <code class=\"docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code> ou pour <code class=\"docutils literal notranslate\"><span class=\"pre\">migrate</span></code>) est respectée dans la mesure du possible, mais ce n’est pas une garantie ; toute autre application concernée dans l’optique de la gestion des dépendances sera également impliquée dans l’opération.</p>\n<p>Les applications sans migrations ne doivent pas posséder de relations (ForeignKey`, <code class=\"docutils literal notranslate\"><span class=\"pre\">ManyToManyField</span></code>, etc.) vers de applications avec migrations. Cela peut parfois marcher, mais Django ne le garantit aucunement.</p>\n</section>\n<section id=\"migration-files\">\n<span id=\"id1\"></span><h2>Fichiers de migrations<a class=\"heading-anchor\" href=\"#migration-files\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les migrations sont stockées sous forme de fichiers sur disque nommés « fichiers de migrations ». Ces fichiers sont en réalité des fichiers Python normaux avec une structure d’objets convenue, rédigés dans un style déclaratif.</p>\n<p>Un fichier de migration simple ressemble à ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><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\">migrations</span><span class=\"p\">,</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"s1\">&#39;migrations&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_initial&#39;</span><span class=\"p\">)]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">DeleteModel</span><span class=\"p\">(</span><span class=\"s1\">&#39;Tribble&#39;</span><span class=\"p\">),</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">AddField</span><span class=\"p\">(</span><span class=\"s1\">&#39;Author&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;rating&#39;</span><span class=\"p\">,</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">IntegerField</span><span class=\"p\">(</span><span class=\"n\">default</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Lorsque Django charge un fichier de migration (sous forme de module Python), Django recherche une sous-classe de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.migrations.Migration</span></code> nommée <code class=\"docutils literal notranslate\"><span class=\"pre\">Migration</span></code>. Il inspecte ensuite cet objet en cherchant quatre attributs, parmi lesquels deux sont utilisés la plupart du temps :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code>, une liste de migrations dont celle-ci dépend.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">operations</span></code>, une liste de classes <code class=\"docutils literal notranslate\"><span class=\"pre\">Operation</span></code> définissant ce que fait cette migration.</p></li>\n</ul>\n<p>L’élément central, c’est les opérations ; il s’agit d’un ensemble d’instructions déclaratives indiquant à Django quelles sont les modifications de schéma qu’il doit effectuer. Django les analyse et construit une représentation en mémoire de tous ces changements de schéma pour toutes les applications, puis utilise cela pour générer le code SQL qui procédera aux modifications de schéma.</p>\n<p>Cette structure en mémoire est également utilisée pour calculer les différences entre les modèles et l’état actuel des migrations ; Django parcourt toutes les modifications dans l’ordre en les appliquant à un ensemble de modèles en mémoire afin d’aboutir à l’état des modèles à l’instant de la dernière exécution de <code class=\"docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code>. Il utilise ensuite ces modèles pour les comparer à ceux qui se trouvent dans les fichiers <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code> afin de déterminer ce qui a changé.</p>\n<p>Il est rarement nécessaire de devoir modifier des fichiers de migration à la main, mais il est tout à fait possible de les écrire manuellement en cas de besoin. Certaines des opérations les plus complexes ne sont pas détectables automatiquement et ne sont donc disponibles que si on les écrit manuellement ; il ne faut donc pas avoir peur de modifier les migrations en cas de nécessité.</p>\n<section id=\"custom-fields\">\n<h3>Champs personnalisés<a class=\"heading-anchor\" href=\"#custom-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il n’est pas possible de modifier le nombre de paramètres positionnels dans un champ personnalisé déjà migré sans générer une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">TypeError</span></code>. L’ancienne migration appellera la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code> modifiée avec l’ancienne signature. Si donc vous avez besoin d’un nouveau paramètre, créez plutôt un paramètre nommé et ajoutez quelque chose comme  <code class=\"docutils literal notranslate\"><span class=\"pre\">assert</span> <span class=\"pre\">'nom_du_paramètre'</span> <span class=\"pre\">in</span> <span class=\"pre\">kwargs</span></code> dans le constructeur.</p>\n</section>\n<section id=\"model-managers\">\n<span id=\"using-managers-in-migrations\"></span><h3>Gestionnaires de modèles<a class=\"heading-anchor\" href=\"#model-managers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous le souhaitez, il est possible de sérialiser les gestionnaires d’objets dans les migrations pour qu’ils soient disponibles lors des opérations <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a>. Cela peut se faire en définissant un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">use_in_migrations</span></code> sur la classe du gestionnaire :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"n\">use_in_migrations</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">MyManager</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Si vous utilisez la fonction <a class=\"reference internal\" href=\"/fr/3.0/topics/db/managers/#django.db.models.from_queryset\" title=\"django.db.models.from_queryset\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">from_queryset()</span></code></a> pour générer dynamiquement une classe de gestionnaire, il est nécessaire d’hériter de la classe générée pour la rendre importable :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyManager</span><span class=\"p\">(</span><span class=\"n\">MyBaseManager</span><span class=\"o\">.</span><span class=\"n\">from_queryset</span><span class=\"p\">(</span><span class=\"n\">CustomQuerySet</span><span class=\"p\">)):</span>\n    <span class=\"n\">use_in_migrations</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">MyManager</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Veuillez vous référer aux notes sur les <a class=\"reference internal\" href=\"#historical-models\"><span class=\"std std-ref\">Modèles historiques</span></a> dans les migrations pour connaître les implications que cela génère.</p>\n</section>\n<section id=\"initial-migrations\">\n<h3>Migrations initiales<a class=\"heading-anchor\" href=\"#initial-migrations\"><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.migrations.Migration.initial\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Migration.</span></span><span class=\"sig-name descname\"><span class=\"pre\">initial</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.Migration.initial\"><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 « migrations initiales » d’une application sont celles qui créent la première version des tables de l’application. Une application possède normalement une seule migration initiale, mais dans certains cas présentant des interdépendances de modèles complexes, elle peut en avoir deux ou même plus.</p>\n<p>Les migrations initiales sont marquées avec un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">initial</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code> sur la classe de migration. Si cet attribut est absent, une migration est tout de même considérée comme « initiale » s’il s’agit de la première migration de l’application (c’est-à-dire qu’elle ne présente aucune dépendance sur d’autres migrations de la même application).</p>\n<p>Lorsque l’option <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#cmdoption-migrate-fake-initial\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">migrate</span> <span class=\"pre\">--fake-initial</span></code></a> est utilisée, ces migrations initiales sont traitées spécialement. Pour une migration initiale qui crée une ou plusieurs tables (opérations <code class=\"docutils literal notranslate\"><span class=\"pre\">CreateModel</span></code>), Django vérifie que toutes ces tables existent déjà dans la base de données et considère alors la migration comme appliquée. De même, pour une migration qui ajoute un ou plusieurs champs (opérations <code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code>), Django vérifie que toutes les colonnes concernées existent déjà dans la base de données et considère la migration comme appliquée le cas échéant. Sans <code class=\"docutils literal notranslate\"><span class=\"pre\">--fake-initial</span></code>, les migrations initiales sont traitées exactement comme toutes les autres migrations.</p>\n</section>\n<section id=\"history-consistency\">\n<span id=\"migration-history-consistency\"></span><h3>Cohérence de l’historique<a class=\"heading-anchor\" href=\"#history-consistency\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Comme discuté précédemment, il peut être nécessaire de réconcilier manuellement des migrations lorsque deux branches de développement sont fusionnées. Lors de l’édition des dépendances de migration, il arrive qu’on crée involontairement un état historique incohérent où une migration a été appliquée mais pas certaines de ses dépendances. C’est une indication claire que les dépendances ne sont pas correctes, Django va donc refuser d’exécuter les migrations en d’en créer de nouvelles tant que ce n’est pas corrigé. Lors de l’utilisation de plusieurs bases de données, il est possible de faire appel à la méthode <a class=\"reference internal\" href=\"/fr/3.0/topics/db/multi-db/#allow_migrate\" title=\"allow_migrate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">allow_migrate()</span></code></a> des <a class=\"reference internal\" href=\"/fr/3.0/topics/db/multi-db/#topics-db-multi-db-routing\"><span class=\"std std-ref\">routeurs de base de données</span></a> pour indiquer pour quelles bases de données <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> va contrôler l’historique.</p>\n</section>\n</section>\n<section id=\"adding-migrations-to-apps\">\n<h2>Ajout de migrations aux applications<a class=\"heading-anchor\" href=\"#adding-migrations-to-apps\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les nouvelles applications sont préconfigurées pour accepter les migrations, il est possible d’ajouter des migrations en exécutant <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> après avoir effectué un certain nombre de modifications.</p>\n<p>Si l’application possède déjà des modèles et des tables de base de données et qu’elle n’a pas encore de migrations (par exemple parce que vous l’avez créée avec une version précédente de Django), vous allez devoir la convertir en vue de l’utilisation des migrations en exécutant :</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>$ python manage.py makemigrations your_app_label\n</code></pre></div>\n<p>Cela va créer une nouvelle migration initiale pour l’application. Ensuite, lancez <code class=\"docutils literal notranslate\"><span class=\"pre\">python</span> <span class=\"pre\">manage.py</span> <span class=\"pre\">migrate</span> <span class=\"pre\">--fake-initial</span></code>, et Django détectera qu’une migration initiale est présente <em>et</em> que les tables qu’il doit créer existent déjà ; il va alors marquer la migration comme déjà appliquée (sans l’option <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#cmdoption-migrate-fake-initial\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">migrate</span> <span class=\"pre\">--fake-initial</span></code></a>, la commande produirait une erreur car les tables qu’elle essayerait de créer existent déjà).</p>\n<p>Notez que cela ne fonctionne qu’à deux conditions :</p>\n<ul class=\"simple\">\n<li><p>Les modèles n’ont pas été modifiés depuis la création des tables correspondantes. Pour que les migrations fonctionnent, vous devez <em>d’abord</em> créer la migration initiale, puis faire les modifications, car Django compare les modifications aux fichiers de migration, pas à la base de données.</p></li>\n<li><p>La base de données n’a pas été modifiée manuellement. Django n’est pas capable de détecter que la base de données ne correspond pas aux modèles, et au moment où les migrations essaieront de modifier ces tables, vous obtiendrez des erreurs.</p></li>\n</ul>\n</section>\n<section id=\"reversing-migrations\">\n<span id=\"id2\"></span><h2>Inversion des migrations<a class=\"heading-anchor\" href=\"#reversing-migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les migrations peuvent être inversées avec <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a> en passant le numéro de la migration précédente. Par exemple, pour inverser la migration <code class=\"docutils literal notranslate\"><span class=\"pre\">books.0003</span></code>:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-0-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>manage.py<span class=\"w\"> </span>migrate<span class=\"w\"> </span>books<span class=\"w\"> </span><span class=\"m\">0002</span>\n<span class=\"go\">Operations to perform:</span>\n<span class=\"go\">  Target specific migration: 0002_auto, from books</span>\n<span class=\"go\">Running migrations:</span>\n<span class=\"go\">  Rendering model states... DONE</span>\n<span class=\"go\">  Unapplying books.0003_auto... OK</span>\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-0-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</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=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py manage.py migrate books 0002\n<span class=\"go\">Operations to perform:</span>\n<span class=\"go\">  Target specific migration: 0002_auto, from books</span>\n<span class=\"go\">Running migrations:</span>\n<span class=\"go\">  Rendering model states... DONE</span>\n<span class=\"go\">  Unapplying books.0003_auto... OK</span>\n</code></pre></div></div></div>\n<p>Si vous souhaitez défaire toutes les migrations appliquées d’une application, utilisez le terme <code class=\"docutils literal notranslate\"><span class=\"pre\">zero</span></code>:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-1-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>manage.py<span class=\"w\"> </span>migrate<span class=\"w\"> </span>books<span class=\"w\"> </span>zero\n<span class=\"go\">Operations to perform:</span>\n<span class=\"go\">  Unapply all migrations: books</span>\n<span class=\"go\">Running migrations:</span>\n<span class=\"go\">  Rendering model states... DONE</span>\n<span class=\"go\">  Unapplying books.0002_auto... OK</span>\n<span class=\"go\">  Unapplying books.0001_initial... OK</span>\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-1-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</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=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py manage.py migrate books zero\n<span class=\"go\">Operations to perform:</span>\n<span class=\"go\">  Unapply all migrations: books</span>\n<span class=\"go\">Running migrations:</span>\n<span class=\"go\">  Rendering model states... DONE</span>\n<span class=\"go\">  Unapplying books.0002_auto... OK</span>\n<span class=\"go\">  Unapplying books.0001_initial... OK</span>\n</code></pre></div></div></div>\n<p>Une migration est irréversible si elle contient au moins une opération irréversible. Si on tente d’inverser une telle migration, une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">IrreversibleError</span></code> sera générée :</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-2-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>manage.py<span class=\"w\"> </span>migrate<span class=\"w\"> </span>books<span class=\"w\"> </span><span class=\"m\">0002</span>\n<span class=\"go\">Operations to perform:</span>\n<span class=\"go\">  Target specific migration: 0002_auto, from books</span>\n<span class=\"go\">Running migrations:</span>\n<span class=\"go\">  Rendering model states... DONE</span>\n<span class=\"go\">  Unapplying books.0003_auto...Traceback (most recent call last):</span>\n<span class=\"go\">django.db.migrations.exceptions.IrreversibleError: Operation &lt;RunSQL  sql=&#39;DROP TABLE demo_books&#39;&gt; in books.0003_auto is not reversible</span>\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-2-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</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=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py manage.py migrate books 0002\n<span class=\"go\">Operations to perform:</span>\n<span class=\"go\">  Target specific migration: 0002_auto, from books</span>\n<span class=\"go\">Running migrations:</span>\n<span class=\"go\">  Rendering model states... DONE</span>\n<span class=\"go\">  Unapplying books.0003_auto...Traceback (most recent call last):</span>\n<span class=\"gp\">django.db.migrations.exceptions.IrreversibleError: Operation &lt;RunSQL  sql=&#39;DROP TABLE demo_books&#39;&gt;</span> in books.0003_auto is not reversible\n</code></pre></div></div></div>\n</section>\n<section id=\"historical-models\">\n<span id=\"id3\"></span><h2>Modèles historiques<a class=\"heading-anchor\" href=\"#historical-models\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Lorsque vous exécutez des migrations, Django se base sur des versions historiques des modèles stockées dans les fichiers de migration. Si vous rédigez du code Python en utilisant l’opération <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> ou si vous avez des méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">allow_migrate</span></code> sur vos routeurs de base de données, vous <strong>devez utiliser</strong> ces versions historisées de modèles et non pas les importer directement.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Si vous importez des modèles directement plutôt que d’utiliser les modèles historisés, vos migrations <em>peuvent fonctionner initialement</em>, mais échoueront dans le futur lorsque vous essaierez de relancer des anciennes migrations (ce qui arrive habituellement lors d’une nouvelle installation qui rejoue toutes les migrations pour créer la base de données).</p>\n<p>Cela signifie que les problèmes de modèles historisés peuvent ne pas apparaître immédiatement. Si vous rencontrez ce genre de problème, il est correct de modifier la migration pour utiliser les modèles historisés au lieu des importations directes et de valider ces modifications.</p>\n</aside>\n<p>Comme il n’est pas possible de sérialiser du code Python arbitraire, ces modèles historiques ne posséderont pas de méthodes personnalisées que vous auriez pu définir. Ils auront cependant les mêmes champs, relations, gestionnaires (pour ceux qui possèdent l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">use_in_migrations</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code>) et options <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> (également historiques, pouvant donc être différents des éléments actuels).</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Cela signifie que des méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> personnalisées ne seront PAS appelées pour les objets manipulés dans les migrations, de la même manière que des constructeurs ou des méthodes d’instance personnalisées ne sont PAS accessibles. Planifiez avec précaution !</p>\n</aside>\n<p>Les références à des fonctions dans les options de champ telles que <code class=\"docutils literal notranslate\"><span class=\"pre\">upload_to</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">limit_choices_to</span></code> et les déclarations de gestionnaire de modèle ayant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">use_in_migrations</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code> sont sérialisées dans les migrations, ce qui fait que ces fonctions et classes doivent être conservées quelque part dans le code aussi longtemps que des migrations les référencent. Il s’agit également de conserver les <a class=\"reference internal\" href=\"/fr/3.0/howto/custom-model-fields/\"><span class=\"doc\">champs de modèle personnalisés</span></a>, car ils sont importés directement par les migrations.</p>\n<p>De plus, les classes de base concrètes des modèles sont stockées sous forme de pointeurs, il faut donc toujours conserver ces classes de base quelque part aussi longtemps qu’une migration contient une référence vers elles. Le côté positif est que les méthodes et gestionnaires de ces classes de base héritent de façon normale, ce qui fait que si vous avez absolument besoin d’y avoir accès, une possibilité est de les déplacer dans une classe parente.</p>\n<p>Pour supprimer d’anciennes références, vous pouvez <a class=\"reference internal\" href=\"#migration-squashing\"><span class=\"std std-ref\">fusionner les migrations</span></a> ou, s’il n’y a pas trop de références, les copier dans les fichiers de migration.</p>\n</section>\n<section id=\"considerations-when-removing-model-fields\">\n<span id=\"migrations-removing-model-fields\"></span><h2>Considérations lors de la suppression de champs de modèles<a class=\"heading-anchor\" href=\"#considerations-when-removing-model-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Dans le même ordre d’idée que les considérations sur les « références aux fonctions historiques » dans la section précédente, la suppression de champs de modèles personnalisés d’un projet ou d’une application tierce posera un problème si ces champs sont référencés dans d’anciennes migrations.</p>\n<p>Pour vous assister dans cette situation, Django fournit quelques attributs de champs de modèle qui peuvent aider à rendre obsolètes des champs de modèle à l’aide de l” <a class=\"reference internal\" href=\"/fr/3.0/topics/checks/\"><span class=\"doc\">infrastructure des contrôles systèmes</span></a>.</p>\n<p>Ajoutez l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">system_check_deprecated_details</span></code> au champ de modèle concerné de cette manière :</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\">IPAddressField</span><span class=\"p\">(</span><span class=\"n\">Field</span><span class=\"p\">):</span>\n    <span class=\"n\">system_check_deprecated_details</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;msg&#39;</span><span class=\"p\">:</span> <span class=\"p\">(</span>\n            <span class=\"s1\">&#39;IPAddressField has been deprecated. Support for it (except &#39;</span>\n            <span class=\"s1\">&#39;in historical migrations) will be removed in Django 1.9.&#39;</span>\n        <span class=\"p\">),</span>\n        <span class=\"s1\">&#39;hint&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Use GenericIPAddressField instead.&#39;</span><span class=\"p\">,</span>  <span class=\"c1\"># optional</span>\n        <span class=\"s1\">&#39;id&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fields.W900&#39;</span><span class=\"p\">,</span>  <span class=\"c1\"># pick a unique ID for your field.</span>\n    <span class=\"p\">}</span>\n</code></pre></div>\n<p>Après une période d’obsolescence de votre choix (deux ou trois versions principales pour les champs propres à Django), modifiez l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">system_check_deprecated_details</span></code> en <code class=\"docutils literal notranslate\"><span class=\"pre\">system_check_removed_details</span></code> et mettez à jour le dictionnaire selon le modèle suivant :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">IPAddressField</span><span class=\"p\">(</span><span class=\"n\">Field</span><span class=\"p\">):</span>\n    <span class=\"n\">system_check_removed_details</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;msg&#39;</span><span class=\"p\">:</span> <span class=\"p\">(</span>\n            <span class=\"s1\">&#39;IPAddressField has been removed except for support in &#39;</span>\n            <span class=\"s1\">&#39;historical migrations.&#39;</span>\n        <span class=\"p\">),</span>\n        <span class=\"s1\">&#39;hint&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Use GenericIPAddressField instead.&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;id&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fields.E900&#39;</span><span class=\"p\">,</span>  <span class=\"c1\"># pick a unique ID for your field.</span>\n    <span class=\"p\">}</span>\n</code></pre></div>\n<p>Il faut toujours conserver les méthodes de champ qui lui sont nécessaires pour fonctionner dans le contexte de migrations de base de données, telles que <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">deconstruct()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">get_internal_type()</span></code>. Conservez ce champ historisé aussi longtemps que des migrations le référençant existent encore. Par exemple, après avoir fusionné des migrations et effacé les anciennes, il est alors possible de supprimer complètement cet ancien champ.</p>\n</section>\n<section id=\"data-migrations\">\n<span id=\"id4\"></span><h2>Migrations de données<a class=\"heading-anchor\" href=\"#data-migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>En plus de modifier le schéma de base de données, les migrations peuvent aussi être utilisées pour modifier les données mêmes de la base de données, conjointement avec le schéma, si vous le souhaitez.</p>\n<p>Les migrations qui modifient des données sont généralement appelées des « migrations de données » ; il est préférable d’en faire des migrations séparées, en parallèle des migrations de schéma.</p>\n<p>Django ne sait pas générer automatiquement des migrations de données à votre place, comme il le fait pour les migrations de schéma, mais il n’est pas très compliqué de les écrire. Les fichiers de migration dans Django sont composés d”<a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/\"><span class=\"doc\">Operations</span></a>, et la principale opération utilisée pour les migrations de données est <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a>.</p>\n<p>Pour commencer, créez un fichier de migration vide qui constituera votre point de départ (Django place le fichier au bon endroit, suggère un nom et ajoute les dépendances pour vous) :</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\">python</span> <span class=\"n\">manage</span><span class=\"o\">.</span><span class=\"n\">py</span> <span class=\"n\">makemigrations</span> <span class=\"o\">--</span><span class=\"n\">empty</span> <span class=\"n\">yourappname</span>\n</code></pre></div>\n<p>Puis, ouvrez le fichier ; il devrait ressembler à quelque chose 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=\"c1\"># Generated by Django A.B on YYYY-MM-DD HH:MM</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\">migrations</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;yourappname&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_initial&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Tout ce qu’il vous reste à faire est de créer une nouvelle fonction et de demander à <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> de l’appeler. <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> s’attend à un objet exécutable en paramètre qui accepte lui-même deux paramètres : le premier est un <a class=\"reference internal\" href=\"/fr/3.0/ref/applications/\"><span class=\"doc\">registre d’applications</span></a> contenant les versions historisées de tous les modèles qui y sont chargés afin de correspondre à l’endroit où se situe la migration dans l’historique, et le second est une classe <a class=\"reference internal\" href=\"/fr/3.0/ref/schema-editor/\"><span class=\"doc\">SchemaEditor</span></a> permettant d’effectuer manuellement des modifications de schéma de la base de données (mais prenez garde, de telles modifications pourraient embrouiller l’auto-détecteur de migrations !).</p>\n<p>Écrivons une migration qui remplit notre nouveau champ <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> avec les valeurs combinées de <code class=\"docutils literal notranslate\"><span class=\"pre\">first_name</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">last_name</span></code> (nous sommes retombés sur nos pieds et avons réalisé que tout le monde n’a pas forcément un nom et un prénom). Tout ce que nous avons à faire est d’utiliser le modèle historique et de parcourir chaque ligne :</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\">migrations</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">combine_names</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"c1\"># We can&#39;t import the Person model directly as it may be a newer</span>\n    <span class=\"c1\"># version than this migration expects. We use the historical version.</span>\n    <span class=\"n\">Person</span> <span class=\"o\">=</span> <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">get_model</span><span class=\"p\">(</span><span class=\"s1\">&#39;yourappname&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Person&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">for</span> <span class=\"n\">person</span> <span class=\"ow\">in</span> <span class=\"n\">Person</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">():</span>\n        <span class=\"n\">person</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">=</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=\"n\">person</span><span class=\"o\">.</span><span class=\"n\">first_name</span><span class=\"p\">,</span> <span class=\"n\">person</span><span class=\"o\">.</span><span class=\"n\">last_name</span><span class=\"p\">)</span>\n        <span class=\"n\">person</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;yourappname&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_initial&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">combine_names</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Une fois que c’est fait, nous pouvons lancer normalement <code class=\"docutils literal notranslate\"><span class=\"pre\">python</span> <span class=\"pre\">manage.py</span> <span class=\"pre\">migrate</span></code> et la migration de données sera exécutée comme toute autre migration.</p>\n<p>Il est possible de passer un second objet exécutable à <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> pour exécuter toute logique adéquate dans le cas d’une migration inverse. Si cet objet est omis, la migration inverse générera une exception, le cas échéant.</p>\n<section id=\"accessing-models-from-other-apps\">\n<h3>Accèder aux modèles d’autres applications<a class=\"heading-anchor\" href=\"#accessing-models-from-other-apps\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lorsque vous écrivez une fonction appelée par <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> et qui utilise des modèles issus d’applications autres que celle dans laquelle la migration est située, l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> de la migration doit inclure la dernière migration de chaque application qui est en cause, sinon vous pouvez obtenir une erreur semblable à : <code class=\"docutils literal notranslate\"><span class=\"pre\">LookupError:</span> <span class=\"pre\">Aucune</span> <span class=\"pre\">application</span> <span class=\"pre\">installée</span> <span class=\"pre\">pour</span> <span class=\"pre\">'myappname'</span></code> lorsque vous utilisez <code class=\"docutils literal notranslate\"><span class=\"pre\">apps.get_model()</span></code> pour essayer de récupérer le modèle dans la fonction appelée par <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code>.</p>\n<p>Dans l’exemple suivant, nous avons une migration dans <code class=\"docutils literal notranslate\"><span class=\"pre\">app1</span></code> qui a besoin d’utiliser des modèles dans <code class=\"docutils literal notranslate\"><span class=\"pre\">app2</span></code>. Nous ne sommes pas préoccupés par les détails de <code class=\"docutils literal notranslate\"><span class=\"pre\">move_m1</span></code> mis à part que cette fonction aura besoin d’accéder à des modèles des deux applications. Par conséquent, nous avons ajouté une dépendance qui spécifie la dernière migration de <code class=\"docutils literal notranslate\"><span class=\"pre\">app2</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\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;app1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_initial&#39;</span><span class=\"p\">),</span>\n        <span class=\"c1\"># added dependency to enable using models from app2 in move_m1</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;app2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0004_foobar&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">move_m1</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n</section>\n<section id=\"more-advanced-migrations\">\n<h3>Migrations avancées<a class=\"heading-anchor\" href=\"#more-advanced-migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous êtes intéressé aux opérations de migration plus avancées ou que vous voulez pouvoir écrire votre propre opération, consultez la <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/\"><span class=\"doc\">référence des opérations de migration</span></a> et le guide pratique sur l”<a class=\"reference internal\" href=\"/fr/3.0/howto/writing-migrations/\"><span class=\"doc\">écriture de migrations</span></a>.</p>\n</section>\n</section>\n<section id=\"squashing-migrations\">\n<span id=\"migration-squashing\"></span><h2>Fusion de migrations<a class=\"heading-anchor\" href=\"#squashing-migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Il ne faut pas craindre de créer autant de migrations que nécessaire, ce n’est pas un problème. Le code de migration est optimisé pour traiter des centaines de migrations à la fois sans trop de lenteurs. Cependant, il peut arriver un moment où l’on souhaite réduire un grand nombre de migrations à juste quelques-unes, et c’est là que la fusion des migrations intervient.</p>\n<p>La fusion est l’acte de réduire un ensemble existant de nombreuses migrations à une seule (ou parfois quelques-unes) qui représente toujours les mêmes changements.</p>\n<p>Django opère cela en prenant toutes les migrations existantes, extrayant leurs opérations en les plaçant toutes à la suite, puis exécutant un optimiseur pour essayer de réduire au maximum cette liste d’opérations. Par exemple, il sait que <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.CreateModel\" title=\"django.db.migrations.operations.CreateModel\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CreateModel</span></code></a> et <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.DeleteModel\" title=\"django.db.migrations.operations.DeleteModel\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DeleteModel</span></code></a> s’annulent l’une l’autre et que <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.AddField\" title=\"django.db.migrations.operations.AddField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AddField</span></code></a> peut être intégrée dans <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.CreateModel\" title=\"django.db.migrations.operations.CreateModel\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CreateModel</span></code></a>.</p>\n<p>Une fois que la suite d’opérations a été réduite au minimum, Django écrit le résultat dans une nouvel ensemble de fichiers de migration. Ce nombre minimum dépend de la quantité de dépendances relatives entre les modèles et de la présence d’opérations <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunSQL\" title=\"django.db.migrations.operations.RunSQL\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunSQL</span></code></a> ou <a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> (qui ne peuvent pas subir d’optimisation, sauf si elles sont marquées comme <code class=\"docutils literal notranslate\"><span class=\"pre\">elidable</span></code>).</p>\n<p>Dans ces fichiers, il est indiqué qu’ils remplacent les migrations fusionnées précédentes, ce qui signifie qu’ils peuvent coexister avec les anciens fichiers de migration ; Django choisit intelligemment les fichiers à prendre en compte en fonction de la position actuelle dans l’historique de migration. Si un projet n’a pas encore complètement appliqué un ensemble de migrations qui a été fusionné, Django continue d’utiliser ces anciennes migrations jusqu’au moment de la fusion, après quoi il se rattache à l’historique fusionné, tandis que de nouvelles installations du projet vont utiliser la nouvelle migration fusionnée et laisser de côté les anciennes.</p>\n<p>Cela permet de fusionner des migrations sans perturber des systèmes actuellement en production qui ne sont pas encore totalement à jour. Le processus recommandé est de fusionner, de conserver les anciens fichiers, de valider et publier le résultat, d’attendre jusqu’à ce que tous les systèmes soient mis à jour avec la nouvelle version (ou dans le cas d’une application réutilisable, s’assurer que les utilisateurs mettent à jour en suivant les versions sans en sauter), puis de supprimer les anciens fichiers, de valider et de publier une seconde version.</p>\n<p>La commande qui se charge de tout ceci est <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-squashmigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">squashmigrations</span></code></a>. Transmettez-lui l’étiquette d’application et le nom de la migration jusqu’à laquelle vous souhaitez fusionner, et elle se mettra au travail :</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>$ ./manage.py squashmigrations myapp 0004\nWill squash the following migrations:\n - 0001_initial\n - 0002_some_change\n - 0003_another_change\n - 0004_undo_something\nDo you wish to proceed? [yN] y\nOptimizing...\n  Optimized from 12 operations to 7 operations.\nCreated new squashed migration /home/andrew/Programs/DjangoTest/test/migrations/0001_squashed_0004_undo_somthing.py\n  You should commit this migration but leave the old ones in place;\n  the new migration will be used for new installs. Once you are sure\n  all instances of the codebase have applied the migrations you squashed,\n  you can delete them.\n</code></pre></div>\n<p>Utilisez l’option <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#cmdoption-squashmigrations-squashed-name\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">squashmigrations</span> <span class=\"pre\">--squashed-name</span></code></a> si vous souhaitez définir le nom de la migration fusionnée plutôt que d’utiliser le nom généré automatiquement.</p>\n<p>Sachez que les interdépendances de modèles Django peuvent devenir vraiment complexes et la fusion peut aboutir à des migrations qui ne peuvent pas être exécutées ; il peut soit y avoir un problème d’optimisation (auquel cas vous pouvez essayer une nouvelle fois avec l’option <code class=\"docutils literal notranslate\"><span class=\"pre\">--no-optimize</span></code>, mais il serait aussi judicieux de signaler le problème), soit un problème d’erreur <code class=\"docutils literal notranslate\"><span class=\"pre\">CircularDependencyError</span></code>, et dans ce cas, vous pouvez le résoudre manuellement.</p>\n<p>Pour résoudre manuellement une erreur <code class=\"docutils literal notranslate\"><span class=\"pre\">CircularDependencyError</span></code>, séparez l’une des clés étrangères de la boucle de dépendances circulaires dans une migration distincte, puis déplacez la dépendance sur l’autre application qui la contient. Si vous hésitez, examinez comment <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> s’occupe de ce problème lorsqu’on lui demande de créer de toutes nouvelles migrations à partir de vos modèles. Dans une version future de Django, <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-squashmigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">squashmigrations</span></code></a> sera mise à jour pour qu’elle puisse résoudre ces erreurs par elle-même.</p>\n<p>Après avoir fusionné les migrations, ajoutez la migration résultante en parallèle à celles qu’elle remplace et distribuez cette modification à toutes les instances en production de votre projet, en prenant soin d’exécuter chaque fois <code class=\"docutils literal notranslate\"><span class=\"pre\">migrate</span></code> pour enregistrer la modification dans la base de données.</p>\n<p>Vous devez alors faire passer la migration fusionnée vers une migration normale en :</p>\n<ul class=\"simple\">\n<li><p>supprimant tous les fichiers de migration qu’elle remplace ;</p></li>\n<li><p>mettant à jour toutes les migrations qui dépendent des migrations supprimées pour les faire dépendre de la migration fusionnée ;</p></li>\n<li><p>enlevant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">replaces</span></code> dans la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Migration</span></code> de la migration fusionnée (c’est ce qui permet à Django de savoir qu’il s’agit d’une migration fusionnée).</p></li>\n</ul>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Après avoir créé une migration fusionnée, vous ne pouvez pas refusionner celle-ci avant d’avoir effectué la transition complète vers une migration normale.</p>\n</aside>\n</section>\n<section id=\"serializing-values\">\n<span id=\"migration-serializing\"></span><h2>Sérialisation de valeurs<a class=\"heading-anchor\" href=\"#serializing-values\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les migrations sont des fichiers Python contenant les anciennes définitions de vos modèles. Pour pouvoir les écrire, Django doit donc prendre l’état actuel des modèles et les sérialiser dans un fichier.</p>\n<p>Bien que Django puisse sérialiser la plupart des objets, il y en a certains qui ne peuvent simplement pas être sérialisés en une représentation Python valide. Il n’existe pas de standard Python permettant à une valeur d’être retransformée en code (<code class=\"docutils literal notranslate\"><span class=\"pre\">repr()</span></code> ne fonctionne qu’avec des valeurs basiques et ne définit pas de chemins d’importation).</p>\n<p>Django est capable de sérialiser ce qui suit :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">int</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">float</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">bool</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">str</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">bytes</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">NoneType</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">list</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">set</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">tuple</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">dict</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">range</span></code>.</p></li>\n<li><p>Instances <code class=\"docutils literal notranslate\"><span class=\"pre\">datetime.date</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">datetime.time</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">datetime.datetime</span></code> (y compris celles qui contiennent un fuseau horaire)</p></li>\n<li><p>Instances <code class=\"docutils literal notranslate\"><span class=\"pre\">decimal.Decimal</span></code></p></li>\n<li><p>Instances <code class=\"docutils literal notranslate\"><span class=\"pre\">enum.Enum</span></code></p></li>\n<li><p>Instances <code class=\"docutils literal notranslate\"><span class=\"pre\">uuid.UUID</span></code></p></li>\n<li><p>instances de <a class=\"reference external\" href=\"https://docs.python.org/3/library/functools.html#functools.partial\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">functools.partial()</span></code></a> et de <a class=\"reference external\" href=\"https://docs.python.org/3/library/functools.html#functools.partialmethod\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">functools.partialmethod</span></code></a> qui possèdent des valeurs sérialisables de <code class=\"docutils literal notranslate\"><span class=\"pre\">func</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">args</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">keywords</span></code>.</p></li>\n<li><p>instances <code class=\"docutils literal notranslate\"><span class=\"pre\">LazyObject</span></code> qui décorent une valeur sérialisable.</p></li>\n<li><p>Instances de types énumératifs (ex. <code class=\"docutils literal notranslate\"><span class=\"pre\">TextChoices</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerChoices</span></code>).</p></li>\n<li><p>Tous les champs Django</p></li>\n<li><p>Toute référence de fonction ou de méthode (par ex. <code class=\"docutils literal notranslate\"><span class=\"pre\">datetime.datetime.today</span></code>) (doit être définie au niveau principal du module)</p></li>\n<li><p>Méthodes non liées utilisées depuis l’intérieur du corps de la classe</p></li>\n<li><p>Toute référence de classe (doit être définie au niveau principal du module)</p></li>\n<li><p>Tout objet comportant une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">deconstruct()</span></code> (voir <a class=\"reference internal\" href=\"#custom-deconstruct-method\"><span class=\"std std-ref\">ci-dessous</span></a>)</p></li>\n</ul>\n<aside class=\"version-note version-changed\" data-version=\"2.2\">\n<p class=\"version-note-title\">Changed in Django 2.2</p><p>La prise en charge de la sérialisation de <code class=\"docutils literal notranslate\"><span class=\"pre\">NoneType</span></code> a été ajoutée.</p>\n</aside>\n<p>Django ne peut pas sérialiser :</p>\n<ul class=\"simple\">\n<li><p>Les classes imbriquées</p></li>\n<li><p>Des instances de classe arbitraires (par ex. <code class=\"docutils literal notranslate\"><span class=\"pre\">MaClasse(4.3,</span> <span class=\"pre\">5.7)</span></code>)</p></li>\n<li><p>Les fonctions lambdas</p></li>\n</ul>\n<section id=\"custom-serializers\">\n<span id=\"custom-migration-serializers\"></span><h3>Sérialiseurs personnalisés<a class=\"heading-anchor\" href=\"#custom-serializers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"2.2\">\n<p class=\"version-note-title\">New in Django 2.2</p></aside>\n<p>Vous pouvez sérialiser d’autres types en écrivant un sérialiseur personnalisé. Par exempl, si Django ne savait pas sérialiser <a class=\"reference external\" href=\"https://docs.python.org/3/library/decimal.html#decimal.Decimal\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Decimal</span></code></a> par défaut, vous auriez pu écrire</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\">decimal</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Decimal</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.migrations.serializer</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseSerializer</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.migrations.writer</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">MigrationWriter</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">DecimalSerializer</span><span class=\"p\">(</span><span class=\"n\">BaseSerializer</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">serialize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">repr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">value</span><span class=\"p\">),</span> <span class=\"p\">{</span><span class=\"s1\">&#39;from decimal import Decimal&#39;</span><span class=\"p\">}</span>\n\n<span class=\"n\">MigrationWriter</span><span class=\"o\">.</span><span class=\"n\">register_serializer</span><span class=\"p\">(</span><span class=\"n\">Decimal</span><span class=\"p\">,</span> <span class=\"n\">DecimalSerializer</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Le premier paramètre de <code class=\"docutils literal notranslate\"><span class=\"pre\">MigrationWriter.register_serializer()</span></code> est un type ou un itérable de types qui doivent utiliser ce sérialiseur.</p>\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">serialize()</span></code> de votre sérialiseur doit renvoyer une chaîne contenant la représentation de la valeur dans les migrations et un ensemble de toute importation nécessaire dans la migration.</p>\n</section>\n<section id=\"adding-a-deconstruct-method\">\n<span id=\"custom-deconstruct-method\"></span><h3>Ajout d’une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">deconstruct()</span></code><a class=\"heading-anchor\" href=\"#adding-a-deconstruct-method\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous pouvez permettre à Django de sérialiser vos propres instances de classe personnalisées en définissant une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">deconstruct()</span></code> pour la classe. Elle n’accepte pas de paramètres et doit renvoyer un tuple de trois éléments <code class=\"docutils literal notranslate\"><span class=\"pre\">(path,</span> <span class=\"pre\">args,</span> <span class=\"pre\">kwargs)</span></code>:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> doit contenir le chemin Python vers la classe, avec le nom de la classe inclus en dernier (par exemple, <code class=\"docutils literal notranslate\"><span class=\"pre\">monapp.quelque_chose.MaClasse</span></code>). Si la classe n’est pas définie au premier niveau du module, elle ne peut pas être sérialisée.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">args</span></code> doit être une liste de paramètres positionnels à passer à la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code> de la classe. Tous les éléments de cette liste doivent être eux-mêmes sérialisables.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">kwargs</span></code> doit être un dictionnaire de paramètres nommés à passer à la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code> de la classe. Toutes ses valeurs doivent être elles-mêmes sérialisables.</p></li>\n</ul>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Cette valeur de renvoi est différente de la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">deconstruct()</span></code> des <a class=\"reference internal\" href=\"/fr/3.0/howto/custom-model-fields/#custom-field-deconstruct-method\"><span class=\"std std-ref\">champs personnalisés</span></a> qui renvoie un tuple de quatre éléments.</p>\n</aside>\n<p>Django écrit la valeur sous forme d’instanciation de la classe avec les paramètres donnés, de la même façon qu’il écrit les références aux champs Django.</p>\n<p>Pour éviter qu’une nouvelle migration soit créée lors de chaque exécution de <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a>, vous devriez aussi ajouter une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__eq__()</span></code> à la classe décorée. Cette fonction sera appelée par le système des migrations de Django pour détecter d’éventuels changements d’état.</p>\n<p>Pour autant que tous les paramètres passés au constructeur de la classe sont eux-même sérialisables, vous pouvez utiliser le décorateur de classe <code class=\"docutils literal notranslate\"><span class=\"pre\">&#64;deconstructible</span></code> se trouvant dans <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.deconstruct</span></code> pour ajouter la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">deconstruct()</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.deconstruct</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">deconstructible</span>\n\n<span class=\"nd\">@deconstructible</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyCustomClass</span><span class=\"p\">:</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">foo</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">foo</span> <span class=\"o\">=</span> <span class=\"n\">foo</span>\n        <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__eq__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">other</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">foo</span> <span class=\"o\">==</span> <span class=\"n\">other</span><span class=\"o\">.</span><span class=\"n\">foo</span>\n</code></pre></div>\n<p>Ce décorateur ajoute la logique nécessaire pour capturer et préserver les paramètres lors de leur transmission au constructeur, puis renvoie ces mêmes paramètres lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">deconstruct()</span></code> est appelée.</p>\n</section>\n</section>\n<section id=\"supporting-multiple-django-versions\">\n<h2>Prendre en charge plusieurs versions de Django<a class=\"heading-anchor\" href=\"#supporting-multiple-django-versions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si vous êtes responsable d’une application tierce qui contient des modèles, vous devrez peut-être fournir des migrations qui prennent en charge plusieurs versions de Django. Dans ce cas, vous devez toujours exécuter <a class=\"reference internal\" href=\"/fr/3.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> <strong>avec le plus bas niveau de version de Django vous souhaitez prendre en charge</strong>.</p>\n<p>Le système de migrations maintiendra la compatibilité ascendante selon la même politique que le reste de Django, afin que les fichiers de migration générées sur Django X.Y devraient fonctionner sans modification sur Django X.Y+1. Cependant, le système des migrations ne promet pas de compatibilité descendante. De nouvelles fonctionnalités peuvent être ajoutées, et les fichiers de migration générés avec les nouvelles versions de Django pourront ne pas fonctionner sur les anciennes versions.</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Voir aussi</p>\n<dl class=\"simple\">\n<dt><a class=\"reference internal\" href=\"/fr/3.0/ref/migration-operations/\"><span class=\"doc\">La référence des opérations de migration</span></a></dt><dd><p>Documente l’API des opérations de schéma, les opérations spéciales ainsi que l’écriture de ses propres opérations.</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/fr/3.0/howto/writing-migrations/\"><span class=\"doc\">Le guide pratique sur l’écriture de migrations</span></a></dt><dd><p>Présente la façon de structurer et d’écrire des migrations de base de données pour différents scénarios auxquels vous pourriez être confrontés.</p>\n</dd>\n</dl>\n</aside>\n</section>","rootId":"module-django.db.migrations","toc":[{"title":"Les commandes","anchor":"the-commands","children":[]},{"title":"Bases de données prises en charge","anchor":"backend-support","children":[{"title":"PostgreSQL","anchor":"postgresql","children":[]},{"title":"MySQL","anchor":"mysql","children":[]},{"title":"SQLite","anchor":"sqlite","children":[]}]},{"title":"Procédures","anchor":"workflow","children":[{"title":"Contrôle de versions","anchor":"version-control","children":[]}]},{"title":"Dépendances","anchor":"dependencies","children":[]},{"title":"Fichiers de migrations","anchor":"migration-files","children":[{"title":"Champs personnalisés","anchor":"custom-fields","children":[]},{"title":"Gestionnaires de modèles","anchor":"model-managers","children":[]},{"title":"Migrations initiales","anchor":"initial-migrations","children":[]},{"title":"Cohérence de l’historique","anchor":"history-consistency","children":[]}]},{"title":"Ajout de migrations aux applications","anchor":"adding-migrations-to-apps","children":[]},{"title":"Inversion des migrations","anchor":"reversing-migrations","children":[]},{"title":"Modèles historiques","anchor":"historical-models","children":[]},{"title":"Considérations lors de la suppression de champs de modèles","anchor":"considerations-when-removing-model-fields","children":[]},{"title":"Migrations de données","anchor":"data-migrations","children":[{"title":"Accèder aux modèles d’autres applications","anchor":"accessing-models-from-other-apps","children":[]},{"title":"Migrations avancées","anchor":"more-advanced-migrations","children":[]}]},{"title":"Fusion de migrations","anchor":"squashing-migrations","children":[]},{"title":"Sérialisation de valeurs","anchor":"serializing-values","children":[{"title":"Sérialiseurs personnalisés","anchor":"custom-serializers","children":[]},{"title":"Ajout d’une méthode deconstruct()","anchor":"adding-a-deconstruct-method","children":[]}]},{"title":"Prendre en charge plusieurs versions de Django","anchor":"supporting-multiple-django-versions","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/3.0/topics/"}],"prev":{"docname":"topics/class-based-views/mixins","title":"Utilisation de mixins avec les vues fondées sur les classes","url":"/fr/3.0/topics/class-based-views/mixins/"},"next":{"docname":"topics/files","title":"Gestion des fichiers","url":"/fr/3.0/topics/files/"},"formats":{"html":"/fr/3.0/topics/migrations/","markdown":"/fr/3.0/topics/migrations.md","json":"/fr/3.0/topics/migrations.json"},"source":"https://github.com/django/django/blob/stable/3.0.x/docs/topics/migrations.txt","official":"https://docs.djangoproject.com/fr/3.0/topics/migrations/","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"]}