Makina Blog

Le blog Makina-corpus

Comment migrer vers une version récente de Django ?


Que ce soit pour avoir les dernières fonctionnalités ou les correctifs de sécurité, rester sur une version récente de Django est important pour la pérennité de son projet.

Les versions de Django ne sont pas supportées éternellement. Les versions LTS (Long Term Support) sont maintenues pendant 3 ans, tandis que les autres versions sont maintenues un peu plus d'un an. Nous pouvons également avoir besoin d'une nouvelle fonctionnalité, ou alors les modules utilisés ne fonctionnent plus avec une version de Django plus ancienne.

Dans tous les cas, il est important de prévoir dès le début de pouvoir migrer régulièrement son code vers une version plus récente de Django.

Django - Supported versions policy

Déroulement d'une montée de version

Django explique très bien dans sa documentation comment faire pour monter de version.

Nous rajouterions juste une étape cruciale : s'assurer en amont que son application a des tests unitaires couvrant la majorité du code.

Les étapes principales d'une montée de version sont les suivantes :

Supprimer tous les warnings en amont

Avant de démarrer la montée de version, il est nécessaire de s'assurer d'avoir déjà corrigé tous les warnings d'obsolescence pour sa version actuelle de Django.

La liste complète des notes de mise à jour est disponible sur le site de Django et chaque version décrit la liste des fonctionnalités dépréciées (qui génèrent en général ces fameux warnings, exemple pour la version 4.2).

Pour cela, faire tourner les tests unitaires en activant les warnings :

python -Wa manage.py test

# En exécutant les tests en parallèle
python -Wa manage.py test --parallel

# En exécutant les tests dans le désordre (Django >4.0)
python -Wa manage.py test --shuffle

Et tester son application en activant également les warnings : 

python -Wa manage.py runserver

Pour se simplifier certaines tâches fastidieuses, des outils permettent de mettre à jour automatiquement notre code en fonction de la version de Django cible souhaitée. Nous avons notamment testé avec succès django-upgrade : 

pip install django-upgrade

# Migrer tous les fichiers *.py vers la version 4.2
git ls-files -- '*.py' | xargs django-upgrade --target-version 4.2

django-upgrade ne corrige pas tous les warnings mais c'est une bonne base de départ. django-codemod est un autre outil de ce type qui peut être utilisé en complément.

Mettre à jour Python

Cette page de la documentation Django indique quelles sont les versions de Python compatibles en fonction de chaque version de Django. À noter, qu'il est nécessaire de remonter à d'anciennes versions de cette page pour les versions précédentes de Django.

Pour jouer facilement avec plusieurs versions de Python, vous pouvez utiliser par exemple pyenv. Voici un exemple : 

# Lister toutes les versions de Python 3.11 disponibles
pyenv install -l | grep 3.11
  [...]
  3.11.2
  3.11.3
  3.11.4
  [...]

# Installer Python 3.11.4
pyenv install 3.11.4

# Créer et utiliser un environnement virtuel 
# (nécessite l'extention "pyenv-virtualenv")
pyenv virtualenv 3.11.4 my-virtual-env-3-11-4
pyenv activate my-virtual-env-3-11-4

pyenv-virtualenv permet notamment d'activer/désactiver automatiquement un environnement virtuel en entrant/sortant d'un dossier, il suffit d'y créer un fichier .python-version contenant le nom de l'environnement virtuel souhaité.

Mettre à jour la base de données

Tout dépend de la base de données utilisée 😉. De notre côté, nous privilégions PostgreSQL. Cette page de la documentation Django indique quelles sont les versions de PostgreSQL compatibles pour la version de Django concernée. À noter, qu'il est nécessaire de remonter à d'anciennes versions de cette page pour les versions précédentes de Django.

Mettre à jour Django

pip install -U Django==4.2
# ou si vous gérez vos dépendances via un fichier requirements.txt
# c'est mieux ;)
pip install -r ./requirements.txt

python
>>> import django; django.__version__
'4.2'

# Parfois, des migrations internes à Django sont introduites
python manage.py makemigrations
python manage.py migrate

Le format de certains settings peut changer. Pour vérifier la syntaxe de la nouvelle version, il est possible d'instancier un nouveau site Django, ainsi qu'une première app, avec cette version pour voir le fichier de settings par défaut : 

django-admin startproject django42
cd django42
django-admin startapp myapp

Mettre à jour les modules complémentaires Django

C'est potentiellement la partie la plus délicate, surtout si vous utilisez de nombreux modules complémentaires.

Ainsi, chaque module doit être mis à jour vers sa version la plus récente compatible avec les versions de Django et Python cibles.

Même si une nouvelle version de Django est souvent rapidement suivie par la sortie de dépendances compatibles, pour les modules qui sont maintenus convenablement, trouver la bonne version reste parfois compliqué. Dans ce cas, il faudra penser à regarder les notes de version, les dates de sorties des versions de la dépendance en question, ou encore les classifieurs "Framework" et "Programming Language" renseignés dans la page PyPI du module.

Si un module n'est pas encore compatible, alors il faut vérifier si la migration de version est possible à faire soi-même ou s'il est nécessaire de changer complètement de dépendance. En effet avec le temps certains projets ne sont plus suivis et prendre le temps d'en sélectionner un maintenu régulièrement est beaucoup plus rentable sur le long terme.

Corriger les erreurs

Il est temps de démarrer son projet et de faire tourner les tests en activant les warnings, supprimer tous les nouveaux warnings, voir ci-dessus, et… corriger toutes les erreurs rencontrées !

Les fonctionnalités obsolètes sont indiquées dans les notes de mises à jour. Par exemple pour la 4.2.

​​​On trouvera également les fonctionnalités obsolètes supprimées dans cette version.

Et on recommence avec la prochaine version cible

Tout cela fonctionne en général bien lorsque l'on a seulement quelques versions de retard. Nous préférons quand même mettre régulièrement à jour notre projet pour éviter d'avoir trop de travail d'un coup, même si ce n'est pas toujours possible, comme nous le verrons dans la suite de l'article.

Dans la pratique

En pratique, il faudra déjà faire un choix. L'application va-t-elle être maintenue régulièrement et peut-on donc installer toutes les versions de Django (LTS et versions intermédiaires) ? Ou au contraire faut-il mieux viser les LTS uniquement pour avoir une base plus stable et moins de montées de versions à faire ?

Ensuite, tout dépend de la version de Django actuelle de notre projet. Les versions en dessous de la 1.11 sont en général plus complexes, car de nombreuses fonctionnalités ont été développées sur ces versions.

De manière générale, il est conseillé de faire les mises à jours par palier, de LTS en LTS. Le passage à la 2.0 est un peu spécial car c'est la première version à ne plus supporter Python 2. Les montées de version seraient donc à faire dans l'ordre suivant :

  • Django < 1.8 => Django 1.8
  • Django 1.8 => Django 1.11
  • Python 2 => Python 3
  • Django 1.11 => Django 2.0
  • Django 2.0 => Django 2.2
  • Django 2.2 => Django 3.2
  • Django 3.2 => Django 4.2

Cela sans oublier de faire suivre les dépendances à chaque étape. Il faudra parfois prendre une version plus ancienne de la dépendance, la dernière version n'étant pas compatible avec la version cible de Django, ou adopter une alternative.

En cas de difficulté, il ne faut pas hésiter à passer par des versions de Django intermédiaire.

Désormais vous n'avez plus d'excuse pour garder votre vielle version de Django !

Découvrez nos réalisations Django.

Formations associées

Formations Django

Formation Django initiation

Nantes Du 12 au 14 mars 2024

Voir la formation

Formations Django

Formation Django avancé

À distance (FOAD) Du 9 au 13 décembre 2024

Voir la formation

Formations Django

Formation Django intégration

À distance (FOAD) 11 mai

Voir la formation

Actualités en lien

Image
Django PostgreSQL
07/11/2023

Utiliser des fonctions PostgreSQL dans des contraintes Django

Cet article vous présente comment utiliser les fonctions et les check constraints PostgreSQL en tant que contrainte sur vos modèles Django.

Voir l'article
Image
Agrégateur Geotrek
08/06/2023

Le projet Agrégateur : fusionner des bases de données Geotrek

Le partage et la diffusion des données font partie des problématiques historiques au cœur du projet Geotrek.

Voir l'article
Image
Python_logo_3
08/07/2020

Migrer une application de Python 2 à Python 3

Le support de Python 2 est officiellement terminé, c'est le moment de passer vos applications à Python 3 ! Voici quelques conseils pour réussir cette migration.

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus