Notes de publication de Django 3.2

6 avril 2021

Bienvenue dans Django 3.2 !

Ces notes de publications couvrent les nouvelles fonctionnalités, ainsi que certaines modifications non rétrocompatibles dont il faut être au courant lors la mise à jour depuis Django 3.1 ou des versions plus anciennes. 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.2 a été désigné comme une version prise en charge à long terme (LTS). Elle recevra des mises à jour de sécurité pour au moins 3 ans après sa publication initiale. La prise en charge de la version LTS précédente, Django 2.2, se terminera en avril 2022.

Compatibilité Python

Django 3.2 requiert Python 3.6, 3.7, 3.8, 3.9 ou 3.10 (dès 3.2.9). Nous recommandons vivement et nous ne prenons officiellement en charge que la dernière publication de chaque série.

Quoi de neuf dans Django 3.2

Découverte automatique des classes AppConfig

La plupart des applications réutilisables définissent une sous-classe de AppConfig dans un sous-module apps.py. Elles définissent souvent une variable default_app_config pointant vers cette classe dans leur fichier __init__.py.

Lorsque le sous-module apps.py existe et définit une seule sous-classe AppConfig, Django utilise dorénavant automatiquement cette configuration, il est donc possible de supprimer default_app_config.

default_app_config rendait possible la déclaration simple du chemin d’application dans INSTALLED_APPS (par ex. 'django.contrib.admin') au lieu du chemin complet vers la classe de configuration (par ex. 'django.contrib.admin.apps.AdminConfig'). Cette variable avait été introduite par souci de rétrocompatibilité avec l’ancien style, dans l’intention de basculer l’écosystème dans la syntaxe plus longue, mais ceci ne s’est jamais produit.

Avec la découverte automatique des classes AppConfig, default_app_config n’a plus de raison d’être. Par conséquent, elle a été rendue obsolète.

Lisez Configuration des applications pour des informations plus complètes.

Personnalisation du type des clés primaires auto-générées

Lors de la définition d’un modèle, si aucun champ du modèle ne définit primary_key=True, une clé primaire implicite est créée. Le type de cette clé primaire implicite peut dorénavant être contrôlée par le réglage DEFAULT_AUTO_FIELD et l’attribut AppConfig.default_auto_field. Plus besoin de surcharger les clés primaires dans tous les modèles.

Afin de conserver le comportement historique, la valeur par défaut de DEFAULT_AUTO_FIELD est AutoField. À partir de la version 3.2, les nouveaux projets sont générés avec DEFAULT_AUTO_FIELD définie à BigAutoField. De même, les nouvelles applications sont générées avec AppConfig.default_auto_field définie à BigAutoField. Dans une future version de Django, la valeur par défaut de DEFAULT_AUTO_FIELD sera modifiée en BigAutoField.

Pour éviter des migrations non souhaitées dans le futur, définissez explicitement DEFAULT_AUTO_FIELD à AutoField:

DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

ou configurez ce réglage par application:

from django.apps import AppConfig


class MyAppConfig(AppConfig):
    default_auto_field = "django.db.models.AutoField"
    name = "my_app"

ou même encore par modèle:

from django.db import models


class MyModel(models.Model):
    id = models.AutoField(primary_key=True)

Par anticipation du changement de valeur par défaut, un contrôle système produit un avertissement si vous ne définissez pas explicitement DEFAULT_AUTO_FIELD dans votre projet.

When changing the value of DEFAULT_AUTO_FIELD, migrations for the primary key of existing auto-created through tables cannot be generated currently. See the DEFAULT_AUTO_FIELD docs for details on migrating such tables.

Index fonctionnels

Le nouveau paramètre positionnel *expressions de Index() permet de créer des index fonctionnels sur la base d’expressions et de fonctions de base de données. Par exemple

from django.db import models
from django.db.models import F, Index, Value
from django.db.models.functions import Lower, Upper


class MyModel(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    height = models.IntegerField()
    weight = models.IntegerField()

    class Meta:
        indexes = [
            Index(
                Lower("first_name"),
                Upper("last_name").desc(),
                name="first_last_name_idx",
            ),
            Index(
                F("height") / (F("weight") + Value(5)),
                name="calc_idx",
            ),
        ]

Les index fonctionnels peuvent être ajoutés aux modèles en utilisant l’option Meta.indexes.

Prise en charge de pymemcache

The new django.core.cache.backends.memcached.PyMemcacheCache cache backend allows using the pymemcache library for memcached. pymemcache 3.4.0 or higher is required. For more details, see the documentation on caching in Django.

Nouveaux décorateurs pour le site d’administration

Le nouveau décorateur display() permet d’ajouter facilement des options à des fonctions d’affichage personnalisées pouvant être utilisée dans list_display ou readonly_fields.

De façon similaire, le nouveau décorateur action() permet d’ajouter facilement des options à des fonctions d’action pouvant être utilisée dans actions.

L’utilisation du décorateur @display a l’avantage de rendre possible la syntaxe de décoration @property lorsqu’il est nécessaire d’indiquer des attributs à une méthode personnalisée. Avant cela, il était nécessaire d’utiliser la fonction property() après la définition des attributs nécessaires à la méthode.

L’utilisation de décorateurs a l’avantage de rendre ces options plus accessibles car elles peuvent être suggérées par des utilitaires de complétion dans des éditeurs de code. Ces décorateurs sont de simples commodités et définissent en réalité les mêmes attributs sur les fonctions, sous le capot.

Fonctionnalités mineures

django.contrib.admin

  • ModelAdmin.search_fields autorise désormais la recherche de phrases contenant des espaces, entre guillemets.

  • Les champs liés en lecture seule sont maintenant affichés comme des liens navigables si les modèles cibles sont inscrits dans le site d’administration.

  • Le site d’administration peut maintenant être thématisé, et il contient un thème sombre activé en fonction des réglages du navigateur. Voir Prise en charge des thèmes pour plus de détails.

  • ModelAdmin.autocomplete_fields respecte dorénavant attr:ForeignKey.to_field <django.db.models.ForeignKey.to_field> et ForeignKey.limit_choices_to lors de la recherche d’un modèle lié.

  • Le site d’administration installe doérnavant une vue finale « attrape-tout » qui redirige les utilisateurs non authentifiés vers la page de connexion, que l’URL soit valide ou non. Ceci protège contre une potentielle faille de confidentialité par découverte de modèle.

    Même si ce n’est pas recommandé, il est possible de définir le nouvel attribut AdminSite.final_catch_all_view à False pour désactiver cette vue « attrape-tout ».

django.contrib.auth

  • Le nombre d’itération par défaut du hacheur de mot de passe PBKDF2 a été augmenté de 216’000 à 260’000.

  • La variante par défaut du hacheur de mots de passe Argon2 a été changée en Argon2id. memory_cost et parallelism ont été respectivement augmentées à 102’400 et 8 pour correspondre aux valeurs par défaut de argon2-cffi.

    L’augmentation de la valeur memory_cost fait augmenter la mémoire nécessaire de 512 Ko à 100 Mo. C’est toujours plutôt conservateur, mais peut amener à des problèmes de mémoire dans des environnements restreints. Dans ce genre de cas, il est possible de créer une sous-classe du hacheur existant pour surcharger les valeurs par défaut.

  • L’entropie par défaut du sel des hacheurs de mots de passe Argon2, MD5, PBKDF2 et SHA-1 a été augmentée de 71 à 128 bits.

django.contrib.contenttypes

django.contrib.gis

django.contrib.postgres

  • Le nouvel attribut ExclusionConstraint.include permet de créer des contraintes d’exclusion couvrantes avec PostgreSQL 12+.
  • The new ExclusionConstraint.opclasses attribute allows setting PostgreSQL operator classes.
  • Le nouvel attribut JSONBAgg.ordering détermine l’ordre des éléments agrégés.
  • Le nouvel attribut JSONBAgg.distinct détermine si les valeurs agrégées seront distinctes.
  • L’opération CreateExtension contrôle dorénavant si l’extension existe déjà dans la base de données et saute la migration le cas échéant.
  • Les nouvelles opérations CreateCollation et RemoveCollation permettent de créer et de supprimer des collations avec PostgreSQL. Voir Gestion des collations à l’aide des migrations pour plus de détails.
  • Les requêtes sur les champs ArrayField permettent dorénavant des tableaux (non imbriqués) contenant des expressions dans les parties droites des requêtes.
  • La nouvelle expression OpClass() permet de créer des index fonctionnels sur les expressions avec une classe d’opérateur personnalisée. Voir Index fonctionnels pour plus de détails.

django.contrib.sitemaps

  • Les nouveaux attributs alternates, languages et x_default de Sitemap permettent de générer des versions (alternates) des plans de sites vers des versions traduites de vos pages.

django.contrib.syndication

  • Le nouveau point d’entrée item_comments permet d’indiquer une URL de commentaires par élément de flux.

Moteurs de base de données

  • Les moteurs de base de données de tierce partie peuvent maintenant sauter des tests ou les marquer comme échecs attendus dans la suite de tests de Django en utilisant les nouveaux attributs DatabaseFeatures.django_test_skips` et django_test_expected_failures.

Décorateurs

Signalement d’erreurs

Téléversement de fichiers

Formulaires

Vues génériques

  • Les attributs week_format de class:~django.views.generic.dates.WeekMixin et WeekArchiveView prennent désormais en charge le format de semaine ISO 8601 '%V'.

Commandes d’administration

  • loaddata prend désormais en charge les instantanés stockés dans des archives XZ (.xz) et LZMA (.lzma).
  • dumpdata sait désormais comprimer les données dans les formats bz2, gz, lzma ou xz.
  • makemigrations peut désormais être appelée sans connexion active de base de données. Dans ce cas, le contrôle de cohérence de l’historique des migrations est omis.
  • BaseCommand.requires_system_checks peut dorénavant accepter une liste d’étiquettes. Les contrôles système inscrits avec les étiquettes choisies seront appliqués avant d’exécuter la commande. Dans les versions précédentes, soit tous les contrôles systèmes étaient appliqués, soit aucun.
  • La prise en charge des contenus de terminal colorés sous Windows a été mise à jour. Différents environnements de terminal modernes sont automatiquement détectés, et les options pour activer la prise en charge dans d’autre cas ont été améliorées. Voir Syntaxe colorée pour plus de détails.

Migrations

  • La nouvelle propriété Operation.migration_name_fragment permet de fournir un fragment de nom de fichier qui sera utilisé pour nommer une migration contenant uniquement cette opération.
  • Les migrations prennent désormais en charge la sérialisation des objets chemins purs et concrets des instances pathlib et os.PathLike.

Modèles

  • Le nouveau paramètre no_key de QuerySet.select_for_update(), pris en charge par PostgreSQL, permet d’acquérir des verrous plus faibles qui ne bloquent pas la création de lignes référençant des lignes verrouillées au travers d’une clé étrangère.
  • L’expression When() autorise dorénavant l’utilisation du paramètre condition avec lookups.
  • Les nouveaux attributs Index.include et UniqueConstraint.include permettent de créer des index couvrants et des contraintes de couverture uniques avec PostgreSQL 11+.
  • Le nouvel attribut UniqueConstraint.opclasses permet de définir des classes d’opérateur PostgreSQL.
  • La méthode QuerySet.update() respecte dorénavant la clause order_by() avec MySQL et MariaDB.
  • FilteredRelation() prend désormais en charge les relations imbriquées.
  • Le paramètre of de QuerySet.select_for_update() est désormais autorisé avec MySQL 8.0.1+.
  • L’expression Value() résout désormais automatiquement sa valeur output_field à la sous-classe appropriée de Field, en fonction du type de la valeur value fournie, pour les types bool, bytes, float, int, str, datetime.date, datetime.datetime, datetime.time, datetime.timedelta, decimal.Decimal et uuid.UUID. Par conséquent, la résolution de output_field pour les fonctions de base de données et les expressions combinatoires peuvent désormais planter avec des types mélangés lors de l’utilisation de Value(). Dans de tels cas, il sera nécessaire de définir explicitement le type de champ output_field.
  • La nouvelle méthode QuerySet.alias() permet de créer des alias réutilisables pour des expressions qui n’ont pas besoin d’être sélectionnées mais qui sont utiles pour le filtrage, le tri ou comme faisant partie d’expressions complexes.
  • La nouvelle fonction Collate permet de filtrer et de trier en respectant les collations de base de données indiquées.
  • Le paramètre field_name de QuerySet.in_bulk() accepte dorénavant les champs distincts s’il n’existe qu’un seul champ indiqué dans QuerySet.distinct().
  • Le nouveau paramètre tzinfo des fonctions de base de données TruncDate et TruncTime permettent de tronquer les dates/heures dans un fuseau horaire déterminé.
  • Le nouveau paramètre db_collation de CharField et:attr:TextField <django.db.models.TextField.db_collation> permet de définir une collation de base de données pour le champ.
  • La fonction de base de données Random a été ajoutée.
  • Les Fonctions d’agrégation, F(), OuterRef() et d’autres expressions autorisent désormais l’utilisation de transformations. Voir Les expressions peuvent référencer des transformations pour plus de détails.
  • Le nouveau paramètre durable de atomic() garantit que les modifications effectuées dans le bloc atomique seront validées si le bloc se termine sans erreur. Un bloc atomique imbriqué marqué comme durable produira une exception RuntimeError.
  • La fonction de base de données JSONObject a été ajoutée.

Pagination

  • La nouvelle méthode django.core.paginator.Paginator.get_elided_page_range() permet de générer un intervalle de pages avec certaines valeurs éludées. Lorsqu’il y a beaucoup de pages, ceci peut s’avérer utile pour générer un nombre raisonnable de liens vers des pages dans un gabarit.

Requêtes et réponses

  • Les en-têtes de réponses sont désormais stockées dans HttpResponse.headers. Ceci peut remplacer l’accès traditionnel par interface de style dictionnaire des objets HttpResponse. Les deux interfaces continueront a être prises en charge. Voir Définition de champs d’en-tête pour plus de détails.
  • Le nouveau paramètre headers de class:~django.http.HttpResponse, SimpleTemplateResponse et TemplateResponse permet de définir les en-têtes de réponse headers lors de l’instanciation.

Sécurité

  • Le contenu du réglage SECRET_KEY est dorénavant vérifié lors de son premier accès, plutôt qu’au moment du chargement des réglages. Ceci permet aux commandes d’administration qui ne dépendent pas de SECRET_KEY de s’exécuter sans qu’une valeur soit définie. Par suite de ce changement, l’appel à configure() sans fournir de SECRET_KEY valable, puis poursuivre en accédant plus tard à settings.SECRET_KEY produira une exception ImproperlyConfigured.

  • Les nouvelles méthodes Signer.sign_object() et Signer.unsign_object() permettent de signer des structures complexes. Voir Protection de structures de données complexes pour plus de détails.

    De plus, signing.dumps() et loads() deviennent des raccourcis de TimestampSigner.sign_object() et unsign_object().

Sérialisation

  • Le nouveau sérialiseur JSONL permet d’utiliser le format de lignes JSON avec dumpdata et loaddata. Cela peut être utile pour remplir de grosses bases de données, car les données sont chargées ligne par ligne en mémoire plutôt que d’être chargées d’un coup en entier.

Signaux

Gabarits

Tests

  • Les objets attribués à des attributs de classe dans TestCase.setUpTestData() sont maintenant isolés pour chaque méthode de test. De tels objets doivent maintenant être capables de prendre en charge la copie profonde par copy.deepcopy(). L’attribution d’objets qui ne prennent pas en charge deepcopy() est obsolète et sera supprimée dans Django 4.1.
  • DiscoverRunner active dorénavant faulthandler par défaut. Ceci peut être désactivé en utilisant l’option test --no-faulthandler.
  • DiscoverRunner et la commande d’administration test peut dorénavant mesurer des temps d’exécution, y compris la mise en place de la base de données et le temps total d’exécution. Ceci peut être activé en utilisant l’option test --timing.
  • Client préserve dorénavant la chaîne de requête lorsqu’il suit des redirections 307 et 308.
  • La nouvelle méthode TestCase.captureOnCommitCallbacks() capture dans une liste les fonctions de rappel transmises à transaction.on_commit() . Cela permet de tester de telles fonctions de rappel sans devoir utiliser la classe TransactionTestCase plus lente.
  • TransactionTestCase.assertQuerysetEqual() now supports direct comparison against another queryset rather than being restricted to comparison against a list of string representations of objects when using the default value for the transform argument.

Utilitaires

  • Le nouveau paramètre depth des fonctions django.utils.timesince.timesince() et django.utils.timesince.timeuntil() permet d’indiquer le nombre d’unités de temps adjacentes à renvoyer.

Validateurs

  • Les validateurs intégrés incluent dorénavant la valeur fournie dans l’argument params d’une erreur ValidationError. Cela permet à des messages d’erreur personnalisés d’utiliser le substituant %(value)s.
  • L’opérateur d’égalité de ValidationError ignore dorénavant l’ordre dans messages et params.

Changements incompatibles avec les anciennes versions dans Django 3.2

API de moteur de base de données

Cette section décrit des modifications qui pourraient être nécessaires dans des moteurs de base de données tiers.

  • La nouvelle propriété DatabaseFeatures.introspected_field_types remplace ces capacités :
    • can_introspect_autofield
    • can_introspect_big_integer_field
    • can_introspect_binary_field
    • can_introspect_decimal_field
    • can_introspect_duration_field
    • can_introspect_ip_address_field
    • can_introspect_positive_integer_field
    • can_introspect_small_integer_field
    • can_introspect_time_field
    • introspected_big_auto_field_type
    • introspected_small_auto_field_type
    • introspected_boolean_field_type
  • Pour activer la prise en charge des index couvrants (Index.include) et les contraintes de couverture uniques (UniqueConstraint.include), définissez DatabaseFeatures.supports_covering_indexes à True.
  • Les moteurs de base de données externes doivent implémenter la prise en charge des collations de colonnes de base de données pour CharField et TextField ou définir DatabaseFeatures.supports_collation_on_charfield et DatabaseFeatures.supports_collation_on_textfield à False. Si les collations non déterministes ne sont pas prises en charge, définissez supports_non_deterministic_collations à False.
  • DatabaseOperations.random_function_sql() a été supprimée en faveur de la nouvelle fonction de base de données Random.
  • DatabaseOperations.date_trunc_sql() et DatabaseOperations.time_trunc_sql() acceptent dorénavant le paramètre facultatif tzname afin de tronquer dans un fuseau horaire bien précis.
  • DatabaseClient.runshell() obtient dorénavant les arguments et un dictionnaire facultatif de variables d’environnement pour le client en ligne de commande sous-jacent à partir de la méthode DatabaseClient.settings_to_cmd_args_env(). Les moteurs de bases de données tiers doivent implémenter DatabaseClient.settings_to_cmd_args_env() ou surcharger DatabaseClient.runshell().
  • Les moteurs de bases de données tiers doivent implémenter la prise en charge des index fonctionnels (Index.expressions) ou définir DatabaseFeatures.supports_expression_indexes à False. Si COLLATE ne fait pas partie de l’instruction CREATE INDEX, définissez DatabaseFeatures.collate_as_index_expression à True.

django.contrib.admin

  • Les liens de pagination dans le site d’administration sont dorénavant indicées à partir de 1 au lieu de 0, c’est-à-dire que la chaîne de requête de la première page est ?p=1 au lieu de ?p=0.
  • La nouvelle vue « attrape-tout » du site d’administration casse les motifs d’URL routés après les URL d’administration et dont le préfixe correspond à celui de l’administration. Vous pouvez alors soit ajuster l’ordre de vos URL ou si nécessaire définir AdminSite.final_catch_all_view à False, désactivant ainsi la vue « attrape-tout ». Voir Quoi de neuf dans Django 3.2 pour plus de détails.
  • Les fichiers JavaScript minifiés ne sont plus inclus avec le site d’administration. Si vous devez avoir accès à ces fichiers minifiés, considérez l’utilisation d’une application tierce ou d’un outil de construction externe. Il reste cependant dans le site d’administration la version minifiée des bibliothèques JavaScript externes (par ex. jquery.min.js).
  • ModelAdmin.prepopulated_fields n’exclut plus les mots vides anglais tels que 'a' ou 'an'.

django.contrib.gis

  • La prise en charge de PostGIS 2.2 a été supprimée.
  • Le moteur Oracle clone dorénavant les polygones (et les collections géométriques contenant des polygones) avant de les réorienter et de les enregistrer en base de données. Ils ne sont plus modifiés eux-mêmes. Cela peut se remarquer quand on utilise des polygones après l’enregistrement d’un modèle.

Abandon de la prise en charge de PostgreSQL 9.5

La prise en charge amont de PostgreSQL 9.5 se termine en février 2021. Django 3.2 prend en charge PostgreSQL 9.6 et plus récent.

Abandon de la prise en charge de MySQL 5.6

La fin de la prise en charge amont de MySQL 5.6 est en avril 2021. Django 3.2 prend en charge MySQL 5.7 et plus récent.

Divers

  • Django prend dorénavant en charge les fuseaux horaires non-pytz, tels que ceux du module zoneinfo de Python 3.9+ et ses rétroportages.

  • La méthode non documentée SpatiaLiteOperations.proj4_version() a été renommée en proj_version().

  • slugify() supprime dorénavant les tirets et soulignements en début et fin de texte.

  • The intcomma and intword template filters no longer depend on the USE_L10N setting.

  • La prise en charge de argon2-cffi < 19.1.0 a été abandonnée.

  • Les clés de cache ne contiennent plus la langue lorsque l’internationalisation est désactivée (USE_I18N = False) et que la régionalisation est activée (USE_L10N = True). Après la mise à jour vers Django 3.2 dans une configuration telle que celle-ci, la première requête vers une valeur précédemment en cache produira un défaut de cache.

  • ForeignKey.validate() utilise dorénavant _base_manager au lieu de _default_manager pour vérifier si des instances liées existent.

  • Lorsqu’une application définit une sous-classe de AppConfig dans un sous-module apps.py, Django utilise désormais automatiquement cette configuration, même si elle n’est pas activée avec default_app_config. Définisez default = False dans la sous-classe de AppConfig si vous voulez empêcher ce comportement. Voir Quoi de neuf dans Django 3.2 pour plus de détails.

  • L’instanciation d’un modèle abstrait produit dorénavant une erreur TypeError.

  • Les arguments nommés de setup_databases() sont dorénavant exclusivement des arguments nommés.

  • La fonction non documentée django.utils.http.limited_parse_qsl() a été supprimée. Utilisez urllib.parse.parse_qsl() à la place.

  • django.test.utils.TestContextDecorator utilise dorénavant addCleanup() afin que les nettoyages inscrits dans la méthode setUp() soient appelés avant TestContextDecorator.disable().

  • SessionMiddleware produit dorénavant l’exception exc:~django.contrib.sessions.exceptions.SessionInterrupted au lieu de SuspiciousOperation lorsqu’une session est détruite dans une requête concurrente.

  • L’opérateur d’égalité de django.db.models.Field distingue dorénavant correctement les instances de champ héritées entre modèles. De plus, l’ordre de tels champs est dorénavant défini.

  • La fonction non documentée django.core.files.locks.lock() renvoie dorénavant False si le fichier ne peut être verrouillé, au lieu de produire l’exception BlockingIOError.

  • Le mécanisme de réinitialisation de mot de passe invalide dorénavant les jetons lorsque l’adresse de courriel d’un utilisateur change.

  • La commande makemessages ne traite plus les locales non valables indiquées par l’option makemessages --locale, notamment lorsqu’elles contiennent des tirets ('-').

  • Le champ de formulaire django.contrib.auth.forms.ReadOnlyPasswordHashField est dorénavant désactivé par défaut. Par conséquent, UserChangeForm.clean_password() n’est plus nécessaire pour renvoyer la valeur initiale.

  • Les opérations de cache cache.get_many(), get_or_set(), has_key(), incr(), decr(), incr_version() et decr_version() gèrent maintenant correctement les valeurs None stockées dans le cache, comme pour toute autre valeur, au lieu de faire comme si la clé n’existait pas dans le cache.

    En raison d’une limitation de python-memcached, le comportement précédent a été conservé pour le moteur obsolète MemcachedCache.

  • La version minimum de SQLite prise en charge est passée de 3.8.3 à 3.9.0.

  • CookieStorage stocke dorénavant ses messages dans le format compatible RFC 6265. La prise en charge des cookies utilisant l’ancien format est conservée jusqu’à Django 4.1.

  • La version minimum de asgiref prise en charge est passée de 3.2.10 à 3.3.2.

Fonctionnalités rendues obsolètes dans Django 3.2

Divers

  • L’attribution d’objets ne prenant pas en charge la création de copies profondes avec copy.deepcopy() à des attributs de classe de TestCase.setUpTestData() est obsolète.
  • L’utilisation d’une valeur booléenne dans attr:.BaseCommand.requires_system_checks est osbolète. Utilisez '__all__' au lieu de True, et [] (une liste vide) au lieu de False.
  • L’argument whitelist et l’attribut domain_whitelist de EmailValidator sont obsolètes. Utilisez allowlist au lieu de whitelist et domain_allowlist au lieu de domain_whitelist. Il se peut que vous deviez renommer whitelist dans des migrations existantes.
  • La variable de configuration d’application default_app_config est osbolète, en raison de l’ajout de la découverte automatique des classes AppConfig. Consultez Quoi de neuf dans Django 3.2 pour plus de détails.
  • L’appel automatique à repr() sur un jeu de requête dans TransactionTestCase.assertQuerysetEqual() lors de la comparaison avec des chaînes est obsolète. SI vous avez besoin du comportement précédent, définissez explicitement transform à repr.
  • Le moteur django.core.cache.backends.memcached.MemcachedCache est obsolète car python-memcached présente quelques problèmes et ne semble actuellement plus maintenu. Utilisez plutôt django.core.cache.backends.memcached.PyMemcacheCache ou django.core.cache.backends.memcached.PyLibMCCache.
  • Le format des messages utilisé par django.contrib.messages.storage.cookie.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.1.
Back to Top