# Documentation Django 6.0.7

# 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 de 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`

- Le nouveau paramètre `absolute_max` de `generic_inlineformset_factory()` permet de personnaliser le nombre maximum de formulaires pouvant être instanciés lors de la soumission de données `POST`. Consultez Restriction du nombre maximum de formulaires instanciés pour plus de détails.

- Le nouveau paramètre `can_delete_extra` de `generic_inlineformset_factory()` permet de supprimer la possibilité de supprimer les formulaires supplémentaires. Voir `can_delete_extra` pour plus d’informations.

#### `django.contrib.gis`

- La méthode `GDALRaster.transform()` prend dorénavant en charge `SpatialReference`.

- La classe `DataSource` prend dorénavant en charge `pathlib.Path`.

- La classe `LayerMapping` prend dorénavant en charge `pathlib.Path`.

#### `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.

- The new `JSONBAgg.ordering` attribute determines the ordering of the aggregated elements.

- 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

- Le nouveau décorateur `no_append_slash()` permet à des vues individuelles d’être exclues de la normalisation des URL par `APPEND_SLASH`.

#### Signalement d’erreurs

- Les sous-classes personnalisées de `ExceptionReporter` peuvent maintenant définir les propriétés `html_template_path` et `text_template_path` pour surcharger les gabarits utilisés pour produire les rapports d’exceptions.

#### Téléversement de fichiers

- La nouvelle fonction de rappel `FileUploadHandler.upload_interrupted()` permet de traiter les téléversements interrompus.

#### Formulaires

- Le nouveau paramètre `absolute_max` de `formset_factory()`, `inlineformset_factory()` et `modelformset_factory()` permet de personnaliser le nombre maximum de formulaires pouvant être instanciés lors de la soumission de données `POST`. Voir Restriction du nombre maximum de formulaires instanciés pour plus de détails.

- Le nouveau paramètre `can_delete_extra` de `formset_factory()`, `inlineformset_factory()` et `modelformset_factory()` permet d’enlever la possibilité de supprimer les formulaires supplémentaires. Voir `can_delete_extra` pour plus d’informations.

- Lorsqu’un formulaire de gestion est manquant ou a été manipulé, `BaseFormSet` signale dorénavant une erreur à l’utilisateur plutôt que de produire une exception. Pour personnaliser le message d’erreur, passez le paramètre `error_messages` avec la clé `'missing_management_form'` lors de l’instanciation du jeu de 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

- The new `no_key` parameter for `QuerySet.select_for_update()`, supported on PostgreSQL, allows acquiring weaker locks that don’t block the creation of rows that reference locked rows through a foreign key.

- 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.

- The `of` argument of `QuerySet.select_for_update()` is now allowed on MySQL 8.0.1+.

- `Value()` expression now automatically resolves its `output_field` to the appropriate `Field` subclass based on the type of its provided `value` for `bool`, `bytes`, `float`, `int`, `str`, `datetime.date`, `datetime.datetime`, `datetime.time`, `datetime.timedelta`, `decimal.Decimal`, and `uuid.UUID` instances. As a consequence, resolving an `output_field` for database functions and combined expressions may now crash with mixed types when using `Value()`. You will need to explicitly set the `output_field` in such cases.

- 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.

- The `field_name` argument of `QuerySet.in_bulk()` now accepts distinct fields if there’s only one field specified in `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

- `Signal.send_robust()` journalise dorénavant les exceptions.

#### Gabarits

- Le filtre de gabarit `floatformat` permet dorénavant d’utiliser le suffixe `g` pour forcer le groupement par `THOUSAND_SEPARATOR` pour la locale active.

- Les gabarits mis en cache avec les chargeurs de gabarits en cache sont dorénavant rechargés correctement en mode développement.

#### Tests

- Objects assigned to class attributes in `TestCase.setUpTestData()` are now isolated for each test method. Such objects are now required to support creating deep copies with `copy.deepcopy()`. Assigning objects which don’t support `deepcopy()` is deprecated and will be removed in Django 4.1.

- `DiscoverRunner` now enables `faulthandler` by default. This can be disabled by using the `test --no-faulthandler` option.

- `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` now uses `addCleanup()` so that cleanups registered in the `setUp()` method are called before `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

- Assigning objects which don’t support creating deep copies with `copy.deepcopy()` to class attributes in `TestCase.setUpTestData()` is deprecated.

- 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.