4 août 2020
Bienvenue dans Django 3.1 !
Ces notes de publications couvrent les nouvelles fonctionnalités, ainsi que certaines modifications non rétro-compatibles dont il faut être au courant lors de la mise à jour depuis Django 3.0 ou des versions plus anciennes. Nous avons abandonné certaines fonctionnalités qui ont atteint la fin de leur cycle d’obsolescence et nous avons commencé le processus d’obsolescence de certaines fonctionnalités.
Voir le guide Mise à jour de Django à une version plus récente si vous mettez à jour un projet existant.
Django 3.1 requiert Python 3.6, 3.7, 3.8 ou 3.9 (dès 3.1.3). Nous recommandons vivement et nous ne prenons officiellement en charge que la dernière publication de chaque série.
Django prend dorénavant en charge un chemin de requête pleinement asynchrone, y compris :
Pour débuter avec des vues asynchrones, vous devez déclarer une vue avec async def
:
async def my_view(request):
await asyncio.sleep(0.5)
return HttpResponse("Hello, async world!")
Toutes les fonctionnalités asynchrones sont prises en charge que vous fonctionniez en mode WSGI ou ASGI. Cependant, en utilisant du code asynchrone en mode WSGI, des limites de performance doivent être attendues. Vous pouvez en apprendre davantage sur ce sujet dans la documentation Gestion du code asynchrone.
Vous êtes libre de mélanger des vues, intergiciels et tests asynchrones et synchrones autant que vous voulez. Django va s’assurer que vous vous trouviez toujours dans le bon contexte d’exécution. Nous nous attendons à ce que la plupart des projets conservent la majorité de leurs vues synchrones et n’aient qu’une petite partie de leurs vues en mode asynchrone, mais c’est à vous d’en décider.
L’ORM, la couche de cache et d’autres parties du code de Django qui effectuent des appels réseau à longue durée ne gèrent pas encore l’accès asynchrone. Nous espérons ajouter cette prise ne charge dans les prochaines publications. Les vues asynchrones sont idéales quand vous effectuez beaucoup d’appels d’API ou de requêtes HTTP dans vos vues. Il est maintenant possible d’effectuer tous ces appels HTTP nativement en parallèle pour augmenter considérablement la vitesse d’exécution de vos vues.
La prise ne charge de code asynchrone devrait être entièrement rétrocompatible et nous avons tenté de nous assurer qu’il n’y a pas de régression de performance pour le code synchrone existant. Il ne devrait pas y avoir d’effet décelable pour un projet Django existant.
Django inclut dorénavant des champs models.JSONField
et forms.JSONField
qui peuvent être utilisés avec tous les moteurs de base de données qui offrent ce champ. Les deux champs permettent de personnaliser leurs codeur et décodeur JSON. Le champ de modèle gère l’introspection, les interrogations et transformations qui étaient précédemment disponibles uniquement pour PostgreSQL
from django.db import models
class ContactInfo(models.Model):
data = models.JSONField()
ContactInfo.objects.create(
data={
"name": "John",
"cities": ["London", "Cambridge"],
"pets": {"dogs": ["Rufus", "Meg"]},
}
)
ContactInfo.objects.filter(
data__name="John",
data__pets__has_key="dogs",
data__cities__contains="London",
).delete()
Si votre projet utilise django.contrib.postgres.fields.JSONField
et les champs de formulaires et transformations relatives, vous devriez ajuster les importations pour utiliser les nouveaux champs, puis produire et appliquer une migration de base de données. Pour l’instant, les anciens champs et transformations sont conservés sous forme de références aux nouveaux emplacements et sont marqués comme obsolètes à partir de cette publication.
DEFAULT_HASHING_ALGORITHM
¶The new DEFAULT_HASHING_ALGORITHM
transitional setting allows specifying
the default hashing algorithm to use for encoding cookies, password reset
tokens in the admin site, user sessions, and signatures created by
django.core.signing.Signer
and django.core.signing.dumps()
.
Support for SHA-256 was added in Django 3.1. If you are upgrading multiple
instances of the same project to Django 3.1, you should set
DEFAULT_HASHING_ALGORITHM
to 'sha1'
during the transition, in order to
allow compatibility with the older versions of Django. Note that this requires
Django 3.1.1+. Once the transition to 3.1 is complete you can stop overriding
DEFAULT_HASHING_ALGORITHM
.
Ce réglage est obsolète dès cette publication, car la prise en charge des jetons, cookies, sessions et signatures utilisant l’algorithme SHA-1 sera supprimée dans Django 4.0.
django.contrib.admin
¶Le nouveau filtre django.contrib.admin.EmptyFieldListFilter
pour ModelAdmin.list_filter
permet de filtrer les valeurs vides (chaînes vides et valeurs nulles) dans la vue pour modification de l’administration.
Les filtres dans la barre latérale de droite de la vue pour modification du site d’administration contient dorénavant un lien pour effacer tous les filtres.
Le site d’administration possède maintenant une barre latérale sur les grands écrans pour une navigation simplifiée. Elle est activée par défaut mais peut être désactivée en utilisant un AdminSite
personnalisé et en définissant son attribut AdminSite.enable_nav_sidebar
à False
.
Le rendu de la barre latérale nécessite d’accéder à la requête en cours pour pouvoir définir les possibilités de rôles CSS et ARIA. Cela nécessite la présence de 'django.template.context_processors.request'
dans l’option 'context_processors'
de :setting:`OPTIONS <TEMPLATES-OPTIONS> `.
Les formulaires en ligne extra
initialement vides peuvent dorénavant être supprimés, de la même façon que pour ceux créés dynamiquement.
XRegExp
a été mis à jour de la version 2.0.0 à 3.2.0.
La version intégrée de jQuery a été mise à jour de 3.4.1 vers 3.5.1.
La bibliothèque Select2 a été mise à jour de la version 4.0.7 vers 4.0.13.
django.contrib.auth
¶Le nombre d’itération par défaut du hacheur de mot de passe PBKDF2 a été augmenté de 180’000 à 216’000.
Le nouveau réglage PASSWORD_RESET_TIMEOUT
permet de définir le nombre de secondes pendant lequel un lien de réinitialisation de mot de passe est valide. Ce réglage est privilégié par rapport au réglage obsolète PASSWORD_RESET_TIMEOUT_DAYS
qui sera supprimé dans Django 4.0.
Le mécanisme de réinitialisation de mot de passe utilise dorénavant l’algorithme de hachage SHA-256. La prise en charge des jetons utilisant l’ancien algorithme de hachage restera jusqu’à Django 4.0.
AbstractBaseUser.get_session_auth_hash()
utilise dorénavant l’algorithme de hachage SHA-256. La prise en charge des sessions utilisateurs utilisant l’ancien algorithme de hachage restera jusqu’à Django 4.0.
django.contrib.contenttypes
¶La nouvelle option remove_stale_contenttypes --include-stale-apps
permet de supprimer les types de contenu périmés provenant des applications précédemment installées qui ont été supprimées de INSTALLED_APPS
.
django.contrib.gis
¶La requête relate
est dorénavant prise en charge avec MariaDB.
La propriété LinearRing.is_counterclockwise
a été ajoutée.
AsGeoJSON
est dorénavant prise en charge avec Oracle.
La prise en charge de PostGIS 3 et GDAL3 a été ajoutée.
django.contrib.humanize
¶Le filtre de gabarit intword
prend désormais en charge les nombres entiers négatifs.
django.contrib.postgres
¶La nouvelle classe BloomIndex
permet de créer des index bloom
dans la base de données. La nouvelle opération de migration BloomExtension
installe l’extension bloom
pour ajouter la prise en charge de cet index.
get_FOO_display()
prend dorénavant en charge les champs ArrayField
et RangeField
.
Les nouvelles expressions de requête rangefield.lower_inc
, rangefield.lower_inf
, rangefield.upper_inc
et rangefield.upper_inf
permettent d’interroger RangeField
selon un type de limite.
rangefield.contained_by
prends dorénavant en charge les champs SmallAutoField
, AutoField
, BigAutoField
, SmallIntegerField
et DecimalField
.
SearchQuery
prend dorénavant en charge le type de recherche 'websearch'
avec PostgreSQL 11+.
SearchQuery.value
prend dorénavant en charge les expressions de requête.
La nouvelle classe SearchHeadline
permet de mettre en évidence les résultats de recherche.
La requête search
prend dorénavant en charge les expressions de requête.
Le nouveau paramètre cover_density
de SearchRank
permet de classer les résultats par taux de couverture.
Le nouveau paramètre normalization
de SearchRank
permet de normaliser les classements.
Le nouvel attribut ExclusionConstraint.deferrable
permet de créer des contraintes d’exclusion différables.
django.contrib.sessions
¶Le réglage SESSION_COOKIE_SAMESITE
autorise dorénavant la valeur 'None'
(chaîne) pour indiquer explicitement que le cookie doit être envoyé avec toutes les requêtes (de même site ou inter-sites).
django.contrib.staticfiles
¶Le réglage STATICFILES_DIRS
accepte maintenant les chemins pathlib.Path
.
Le décorateur cache_control()
et la méthode patch_cache_control()
acceptent dorénavant plusieurs noms de champs dans la directive no-cache
de l’en-tête Cache-Control
, en accord avec la RFC 7234 Section 5.2.2.2.
delete()
now returns True
if the key was
successfully deleted, False
otherwise.
Le réglage CSRF_COOKIE_SAMESITE
autorise dorénavant la valeur 'None'
(chaîne) pour indiquer explicitement que le cookie doit être envoyé avec toutes les requêtes (de même site ou inter-sites).
Le réglage EMAIL_FILE_PATH
, utilisé par le moteur de messagerie basé sur des fichiers accepte dorénavant les chemins pathlib.Path
.
django.views.debug.SafeExceptionReporterFilter
filtre dorénavant les valeurs sensibles dans request.META
dans les rapports d’exceptions.
Les nouveaux attributs SafeExceptionReporterFilter.cleansed_substitute
et SafeExceptionReporterFilter.hidden_settings
permettent de personnaliser les réglages sensibles et le filtrage de request.META
dans les rapports d’exceptions.
La vue de débogage technique 404 respecte dorénavant DEFAULT_EXCEPTION_REPORTER_FILTER
lorsqu’elle applique le filtrage des réglages.
Le nouveau réglage DEFAULT_EXCEPTION_REPORTER
permet de fournir une sous-classe de django.views.debug.ExceptionReporter
pour personnaliser la génération des rapports d’exceptions. Voir Rapports d’erreur personnalisés pour plus de détails.
La méthode FileSystemStorage.save()
accepte maintenant les chemins pathlib.Path
.
FileField
et ImageField
acceptent dorénavant un objet exécutable comme valeur de storage
. Cela permet de modifier le stockage utilisé au moment de l’exécution, choisissant par exemple différents stockages en fonction de l’environnement.
ModelChoiceIterator
, utilisé par ModelChoiceField
et ModelMultipleChoiceField
, utilise dorénavant ModelChoiceIteratorValue
qui peut être utilisé par les composants pour accéder aux instances de modèles. Voir Itération sur les choix relationnels pour plus de détails.
django.forms.DateTimeField
accepte dorénavant les dates dans un sous-ensemble des formats de date/heure ISO 8601, y compris le fuseau horaire facultatif, par ex. 2019-10-10T06:47
, 2019-10-10T06:47:23+04:00
ou 2019-10-10T06:47:23Z
. Le fuseau horaire est toujours conservé s’il est présent, et des dates/heures conscientes de leur fuseau sont toujours renvoyées même si USE_TZ
vaut False
.
De plus, DateTimeField
utilise dorénavant DATE_INPUT_FORMATS
en plus de DATETIME_INPUT_FORMATS
lors de la conversion d’une valeur saisie dans un champ vers une valeur datetime
.
MultiWidget.widgets
accepte dorénavant un dictionnaire qui permet de personnaliser les attributs name
des sous-composants.
La nouvelle propriété BoundField.widget_type
peut être utilisée pour ajuster dynamiquement la production des formulaires en fonction du type de composant.
Le réglage LANGUAGE_COOKIE_SAMESITE
autorise dorénavant la valeur 'None'
(chaîne) pour indiquer explicitement que le cookie doit être envoyé avec toutes les requêtes (de même site ou inter-sites).
La prise en charge des traductions en arabe algérien, igbo, kirghize, tadjik et turkmène a été ajoutée.
La nouvelle option check --database
permet d’indiquer des alias de base de données lors de l’exécution des contrôles systèmes database
. Précédemment, ces contrôles étaient activés pour toutes les bases configurées dans DATABASES
lorsqu’on passait le drapeau database
à la commande.
La nouvelle option migrate --check
fait quitter la commande avec un statut différent de 0 lorsque des migrations non appliquées sont détectées.
Le nouveau paramètre returncode
de CommandError
permet de personnaliser le statut de sortie des commandes d’administration.
La nouvelle option dbshell -- PARAMÈTRES
permet de passer des paramètres supplémentaires au client de ligne de commande de la base de données.
Les commandes flush
et sqlflush
incluent dorénavant du code SQL pour réinitialiser les séquences avec SQLite.
La nouvelle fonction ExtractIsoWeekDay
extrait les jours de semaine ISO-8601 des champs DateField
et DateTimeField
, et la nouvelle expression de requête iso_week_day
permet d’interroger selon un jour de semaine ISO-8601.
QuerySet.explain()
prend dorénavant en charge :
le format TREE
de MySQL 8.0.16+ ;
l’option analyze
de MySQL 8.0.18+ et MariaDB.
Le champ PositiveBigIntegerField
a été ajouté ; il est similaire à PositiveIntegerField
sauf qu’il ne permet des valeurs que jusqu’à une certaine limite (dépendante de la base de données). Les valeurs de 0
à 9223372036854775807
sont valables pour toutes les bases de données prises en charge par Django.
La nouvelle option RESTRICT
du paramètre on_delete
de ForeignKey
et de OneToOneField
émule le comportement de la contrainte SQL ON DELETE RESTRICT
.
CheckConstraint.check
now supports boolean expressions.
Les méthodes RelatedManager.add()
, create()
et set()
acceptent dorénavant les objets exécutables comme valeurs du paramètre through_defaults
.
Le nouveau paramètre is_dst
de QuerySet.datetimes()
détermine le traitement des heures non existantes ou ambiguës.
La nouvelle méthode bitxor()
de l’expression F
permet l”opération bit-à-bit XOR.
QuerySet.bulk_create()
définit dorénavant la clé primaire des objets quand on l’utilise avec MariaDB 10.5+
La méthode DatabaseOperations.sql_flush()
génère dorénavant du code SQL plus efficace avec MySQL en utilisant des instructions DELETE
au lieu de TRUNCATE
pour les tables qui ne nécessitent pas la réinitialisation de leurs séquences.
Les fonctions SQLite sont dorénavant marquées comme déterministes
avec Python 3.8+. Cela permet de les utiliser dans des contraintes de contrôle et dans des index partiaux.
Le nouvel attribut UniqueConstraint.deferrable
permet de créer des contraintes d’unicité différables.
Il est maintenant possible d’itérer sur des objets Paginator
pour produire ses pages.
Si ALLOWED_HOSTS
est vide et que DEBUG=True
, les sous-domaines de localhost sont maintenant autorisés dans l’en-tête Host
, par ex. static.localhost
.
HttpResponse.set_cookie()
et HttpResponse.set_signed_cookie()
autorisent désormais l’utilisation de samesite='None'
(chaîne) pour indiquer explicitement que le cookie doit être envoyé avec toutes les requêtes du même site et inter-sites.
La nouvelle méthode HttpRequest.accepts()
renvoie un booléen indiquant si la requête accepte le type MIME donné en fonction de l’en-tête HTTP Accept
.
Le réglage SECURE_REFERRER_POLICY
contient dorénavant par défaut la valeur 'same-origin'
. Avec cette valeur, SecurityMiddleware
définit l’en-tête Politique de référencement à same-origin
pour toutes les réponses qui ne l’ont pas déjà. Cela évite que l’en-tête Referer
soit envoyé à d’autres origines. Si vous avez besoin du comportement précédent, définissez explicitement SECURE_REFERRER_POLICY
à None
.
L’algorithme par défaut de django.core.signing.Signer
, django.core.signing.loads()
et django.core.signing.dumps()
est dorénavant SHA-256. La prise en charge de signatures faites avec l’ancien algorithme SHA-1 sera conservée jusqu’à Django 4.0.
De plus, le nouveau paramètre algorithm
de Signer
permet de personnaliser l’algorithme de hachage.
Les balises de gabarit translate
and blocktranslate
pour la régionalisation dans le code des gabarits ont été renommées. Les anciens alias de ces balises (trans
et blocktrans
) continueront de fonctionner et seront conservés dans le futur proche.
La balise de gabarit include
accepte maintenant des objects itérables de noms de gabarits.
SimpleTestCase
implément dorénavant la méthode debug()
pour permettre de lancer un test sans collecter son résultat et intercepter les exceptions. Ceci peut être utiliser pour pouvoir exécuter les tests avec un débogueur.
Le nouveau réglage de base de données de test MIGRATE
permet de désactiver les migrations pendant la création d’une base de données de test.
DiscoverRunner
can now discard output for
passing tests using the test --buffer
option.
DiscoverRunner
n’exécute plus les contrôles systèmes pour les bases de données qui ne sont pas référencées par les tests.
La terminaison (teardown) de la classe TransactionTestCase
est dorénavant plus rapide avec MySQL en raison des améliorations de la command flush
. Comme effet de bord, cette classe de réinitialise plus automatiquement les séquences dans le processus de terminaison. Activez TransactionTestCase.reset_sequences
si vos tests ont besoin de cette fonctionnalité.
Les convertisseurs de chemin peuvent dorénavant générer ValueError
dans to_url()
pour indiquer qu’aucune correspondance n’a été trouvée dans la résolution inverse des URL.
filepath_to_uri()
accepte maintenant les chemins pathlib.Path
.
parse_duration()
prend dorénavant en charge les séparateurs virgules pour les fractions décimales dans le format ISO 8601.
parse_datetime()
, parse_duration()
et parse_time()
acceptent dorénavant les séparateurs virgules pour les millisecondes.
Le moteur SQLite accepte dorénavant les valeurs pathlib.Path
dans son réglage NAME
.
Le fichier settings.py
généré par la commande startproject
utilise dorénavant un chemin pathlib.Path
au lieu de os.path
pour la construction des chemins du système de fichiers.
Le réglage TIME_ZONE
est désormais autorisé pour les bases de données qui gèrent les fuseaux horaires.
Cette section décrit des modifications qui pourraient être nécessaires dans des moteurs de base de données tiers.
DatabaseOperations.fetch_returned_insert_columns()
exige dorénavant un paramètre supplémentaire returning_params
.
La propriété connection.timezone
vaut dorénavant 'UTC'
par défaut ou la valeur de TIME_ZONE
lorsque USE_TZ
vaut True
avec les bases de données prenant en charge les fuseaux horaires. Précédement, il contenait None
avec les bases de données prenant en charge les fuseaux horaires.
La propriété connection._nodb_connection
a été modifiée en une méthode connection._nodb_cursor()
et renvoie dorénavant un gestionnaire de contexte produisant un curseur et fermant automatiquement ce curseur et sa connexion en sortant du contexte avec l’instruction with
.
DatabaseClient.runshell()
exige dorénavant un paramètre supplémentaire parameters
sous forme de liste de paramètres supplémentaires à transmettre au client de ligne de commande.
Le paramètre positionnel sequences
de DatabaseOperations.sql_flush()
est remplacé par le paramètre reset_sequences
, purement mot-clé et booléen. Si True
, les séquences des tables tronquées seront réinitialisées.
Le paramètre allow_cascade
de DatabaseOperations.sql_flush()
est dorénavant un paramètre uniquement par mot-clé.
Le paramètre positionnel using
de DatabaseOperations.execute_sql_flush()
a été supprimé. La méthode utilise dorénavant la base de données de l’instance appelée.
Les moteurs de base de données externes doivent implémenter la prise en charge de JSONField
ou définir DatabaseFeatures.supports_json_field
à False
. Si le stockage de primitives n’est pas pris en charge, il faut définir DatabaseFeatures.supports_primitives_in_json_field
à False
. Si un type de données JSON spécifique existe, définissez DatabaseFeatures.has_native_json_field
à True
. Si jsonfield.contains
et jsonfield.contained_by
ne sont pas pris en charge, définissez DatabaseFeatures.supports_json_field_contains
à False
.
Les moteurs de base de données de tierce-partie doivent implémenter l’introspection pour JSONField
ou définir can_introspect_json_field
à False
.
La prise en charge amont de MariaDB 10.1 se termine en octobre 2020. Django 3.1 prend en charge MariaDB 10.2 et plus récent.
contrib.admin
¶Le site d’administration ne prend plus en charge le navigateur obsolète Internet Explorer. Consultez la FAQ de l’administration pour plus de détails sur les navigateurs pris en charge.
max_length
de AbstractUser.first_name
a été étendu à 150¶Une migration pour django.contrib.auth.models.User.first_name
a été incluse. Si vous disposez d’un modèle utilisateur personnalisé héritant de AbstractUser
, vous devrez produire et appliquer une migration de base de données pour votre modèle.
Si vous souhaitez conserver la limite de 30 caractères pour les prénoms, utilisez un formulaire personnalisé
from django import forms
from django.contrib.auth.forms import UserChangeForm
class MyUserChangeForm(UserChangeForm):
first_name = forms.CharField(max_length=30, required=False)
Si vous souhaitez conserver cette restriction dans le site d’administration lors de l’édition des utilisateurs, définissez UserAdmin.form
à ce formulaire
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
Les clés de cache utilisées par cache
et générées par make_template_fragment_key()
sont différentes des clés générées par les anciennes versions de Django. Après la mise à jour vers Django 3.1, la première requête vers tout fragment de gabarit mis en cache va devoir remplir à nouveau le cache.
La logique derrière la décision de renvoyer une redirection ou une réponse HTTP 204 dans la vue set_language()
est dorénavant basée sur l’en-tête HTTP Accept
au lieu de la présence de l’en-tête HTTP X-Requested-With
.
Les importations de compatibilité pour django.core.exceptions.EmptyResultSet
dans django.db.models.query
, django.db.models.sql
et django.db.models.sql.datastructures
ont été supprimées.
L’importation de compatibilité pour django.core.exceptions.FieldDoesNotExist
dans django.db.models.fields
a été supprimée.
Les importations de compatibilité pour django.forms.utils.pretty_name()
et django.forms.boundfield.BoundField
dans django.forms.forms
ont été supprimées.
Les importations de compatibilité pour Context
, ContextPopException
et RequestContext
dans django.template.base
ont été supprimées.
L’importation de compatibilité pour django.contrib.admin.helpers.ACTION_CHECKBOX_NAME
dans django.contrib.admin
a été supprimée.
Les réglages STATIC_URL
et MEDIA_URL
définis à des chemins relatifs sont dorénavant préfixés par la valeur SCRIPT_NAME
fournie par le serveur (ou /
si non défini). Ce changement ne devrait pas affecter les réglages définis à des URL valides ou des chemins absolus.
ConditionalGetMiddleware
n’ajoute plus l’en-tête ETag
aux réponses qui ont un contenu content
vide.
Le décorateur django.utils.decorators.classproperty()
a été rendu public et déplacé vers django.utils.functional.classproperty()
.
Le filtre de gabarit floatformat
produit dorénavant 0
(positif) pour les nombres négatifs arrondis à zéro.
Les options Meta.ordering
et Meta.unique_together
des modèles dans les modules django.contrib
qui étaient précédemment des tuples sont maintenant des listes.
Le composant calendrier du site d’administration gère dorénavant les années sur deux chiffres selon la spécification Open Group, c’est-à-dire que les valeurs entre 69 et 99 sont attribuées au siècle précédent et les valeurs entre 0 et 68 sont attribuées au siècle actuel.
Les formats de date uniquement ont été supprimés de la liste par défaut de DATETIME_INPUT_FORMATS
.
Le composant FileInput
ne produit plus d’attribut HTML required
lorsque des données initiales sont présentes.
La classe non documentée django.views.debug.ExceptionReporterFilter
a été supprimée. Comme le spécifie la documentation Rapports d’erreur personnalisés, les classes à placer dans DEFAULT_EXCEPTION_REPORTER_FILTER
doivent hériter de django.views.debug.SafeExceptionReporterFilter
.
L’expiration du cache définie par le décorateur cache_page()
a désormais la priorité sur la directive max-age
de l’en-tête Cache-Control
.
Lorsqu’on passe un champ distant non local dans le paramètre ForeignKey.to_field
, cela génère maintenant une exception FieldError
.
Le réglage SECURE_REFERRER_POLICY
contient désormais 'same-origin'
par défaut. Consultez la section sécurité des nouveautés de Django 3.1 pour plus de détails.
La commande d’administration check
exécute dorénavant les contrôles systèmes database
uniquement pour les alias de base de données indiqués par l’option check --database
.
La commande d’administration migrate
exécute dorénavant les contrôles systèmes database
uniquement pour la base de données de la migration.
Les classes CSS du site d’administration row1
et row2
ont été supprimées en faveur des pseudo-classes :nth-child(odd)
et :nth-child(even)
.
La fonction make_password()
exige dorénavant que son paramètre soit une chaîne ou des octets. D’autres types de données doivent préalablement être forcés à l’un de ces types.
Le paramètre non documenté version
de la fonction AsKML
a été supprimé.
Les sérialiseurs JSON et YAML utilisés par dumpdata
produisent toutes leurs données en Unicode par défaut. SI vous voulez conserver le comportement précédent, passez ensure_ascii=True
au sérialiseur JSON ou allow_unicode=False
au sérialiseur YAML.
Le relanceur automatique ne surveille plus les changements dans les fichiers de traductions intégrés de Django.
La version minimum de mysqlclient
prise en charge est passée de 1.3.13 à 1.4.0.
Les éléments non documentés django.contrib.postgres.forms.InvalidJSONInput
et django.contrib.postgres.forms.JSONString
ont été déplacés vers django.forms.fields
.
La classe django.contrib.postgres.fields.jsonb.JsonAdapter
non documentée a été supprimée.
La balise {% localize off %}
et le filtre unlocalize
ne tiennent plus compte du réglage DECIMAL_SEPARATOR
.
La version minimum de asgiref
prise en charge est passée de 3.2 à 3.2.10.
La classe Media produit dorénavant les balises <script>
sans l’attribut type
pour respecter les recommandations WHATWG.
ModelChoiceIterator
, utilisée par ModelChoiceField
et ModelMultipleChoiceField
produisent dorénavant des choix à 2 tuples contenant des instances de ModelChoiceIteratorValue
comme premier élément value
dans chaque choix. Dans la plupart des cas, le changement se fait de manière transparente, mais si vous avez besoin de la valeur du champ lui-même, utilisez plutôt l’attribut ModelChoiceIteratorValue.value
.
JSONField
spécifique à PostgreSQL¶django.contrib.postgres.fields.JSONField
et django.contrib.postgres.forms.JSONField
sont obsolètes et remplacées par models.JSONField
et forms.JSONField
.
Les transformations non documentées django.contrib.postgres.fields.jsonb.KeyTransform
et django.contrib.postgres.fields.jsonb.KeyTextTransform
sont aussi obsolètes et remplacées par les transformations dans django.db.models.fields.json
.
Les nouveaux éléments JSONField
, KeyTransform
et KeyTextTransform
peuvent être utilisés avec tous les moteurs de base de données pris en charge officiellement par Django.
Le réglage PASSWORD_RESET_TIMEOUT_DAYS
a été rendu obsolète au profit de PASSWORD_RESET_TIMEOUT
.
L’utilisation non documentée de l’expression de requête isnull
avec des valeurs non booléennes dans la partie droite est obsolète, utilisez plutôt True
ou False
.
La classe d’exception tout juste documentée django.db.models.query_utils.InvalidQuery
a été rendue obsolète au profit de FieldDoesNotExist
et de FieldError
.
Le point d’entrée django-admin.py
est obsolète ; il faut plutôt utiliser django-admin
.
La méthode HttpRequest.is_ajax()
est osbolète car elle dépend d’une manière de signifier des appels AJAX propre à jQuery, alors que l’usage actuel tend à utiliser l”API fetch de JavaScript. En fonction de votre cas d’utilisation, vous pouvez soit écrire votre propre méthode de détection AJAX, soit utiliser la nouvelle méthode HttpRequest.accepts()
si votre code se base sur l’en-tête HTTP Accept
du client.
Si vous écrivez votre propre méthode de détection AJAX, request.is_ajax()
peut être reproduite exactement avec la condition request.headers.get('x-requested-with') == 'XMLHttpRequest'
.
La transmission de None
comme premier paramètre de django.utils.deprecation.MiddlewareMixin.__init__()
est obsolète.
Le format de codage des valeurs de cookies utilisé par CookieStorage
est différent du format généré par les anciennes versions de Django. La prise en charge de l’ancien format demeure jusqu’à Django 4.0.
Le format de codage des sessions est différent du format généré par les anciennes versions de Django. La prise en charge de l’ancien format demeure jusqu’à Django 4.0.
Le paramètre à titre purement documentaire providing_args
de Signal
est obsolète. Si vous comptez sur ce paramètre comme information de documentation, vous pouvez déplacer son contenu dans un commentaire de code.
L’appel à django.utils.crypto.get_random_string()
sans paramètre de longueur length
est obsolète.
Le message list
de ModelMultipleChoiceField
a été rendu obsolète au profit de invalid_list
.
La transmission d’alias de colonnes bruts à QuerySet.order_by()
est osbolète. Le même résultat peut être obtenu en passant préalablement les alias dans un objet RawSQL
.
The NullBooleanField
model field is deprecated in favor of
BooleanField(null=True, blank=True)
.
L’alias django.conf.urls.url()
de django.urls.re_path()
est obsolète.
Les balises de gabarit {% ifequal %}
et {% ifnotequal %}
sont obsolètes et {% if %}
doit être utilisé à la place. {% if %}
couvre tous les cas d’utilisation, mais si vous voulez vraiment continuer à utiliser ces balises, elles peuvent être extraites du code de Django vers un de vos modules puis incluses comme balise intégrée dans l’option 'builtins'
de OPTIONS
.
Le réglage temporaire DEFAULT_HASHING_ALGORITHM
est obsolète.
Ces fonctionnalités ont atteint la fin de leur cycle d’obsolescence et sont supprimées dans Django 3.1.
Voir Fonctionnalités rendues obsolètes dans Django 2.2 pour les détails de ces changements, ainsi que pour savoir comment supprimer l’utilisation de ces fonctionnalités.
django.utils.timezone.FixedOffset
a été supprimée.
django.core.paginator.QuerySetPaginator
a été supprimée.
L’attribut Meta.ordering
des modèles n’affecte plus les requêtes GROUP BY
.
django.contrib.postgres.fields.FloatRangeField
et django.contrib.postgres.forms.FloatRangeField
ont été supprimés.
Le réglage FILE_CHARSET
a été supprimé.
django.contrib.staticfiles.storage.CachedStaticFilesStorage
a été supprimée.
La méthode RemoteUserBackend.configure_user()
exige request
comme premier paramètre positionnel.
La prise en charge de SimpleTestCase.allow_database_queries
et de TransactionTestCase.multi_db
a été supprimée.
avr. 05, 2025