# Documentation Django 5.2.8

# Notes de publication de Django 3.0

2 décembre 2019

Bienvenue dans Django 3.0 !

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

## Compatibilité Python

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

La série Django 2.2.x est la dernière à prendre en charge Python 3.5.

## Prise en charge des bibliothèques tierces pour les anciennes versions de Django

Après la publication de Django 3.0, nous suggérons aux applications tierces de ne plus prendre en charge les versions de Django plus anciennes que 2.2. À ce moment, vous devriez pouvoir exécuter les tests de votre projet en utilisant python -Wd afin de faire apparaître les avertissements d’obsolescence. Après avoir corrigé ceux-ci, votre application devrait être compatible avec Django 3.0.

## Quoi de neuf dans Django 3.0

### Prise en charge de MariaDB

Django prend dorénavant officiellement en charge MariaDB 10.1 ou plus récent. Lisez les notes MariaDB pour plus de détails.

### Prise en charge d’ASGI

Django 3.0 commence le voyage vers la fonctionnalité asynchrone de Django en fournissant la prise en charge de l’exécution d’applications ASGI.

Il s’agit d’un ajout en plus de la prise en charge existante du protocole WSGI. Django prévoit de prendre en charge les deux à l’avenir. Les fonctionnalités asychrones ne seront toutefois disponibles que pour les applications fonctionnant avec ASGI.

At this stage async support only applies to the outer ASGI application. Internally everything remains synchronous. Asynchronous middleware, views, etc. are not yet supported. You can, however, use ASGI middleware around Django’s application, allowing you to combine Django with other ASGI frameworks.

Aucun besoin de convertir vos applications sauf si vous souhaitez expérimenter avec du code asynchrone ; si vous souhaitez en savoir plus, vous pouvez lire la documentation sur le déploiement avec ASGI.

Notez qu’un effet de bord de cette nouveauté est que Django sait maintenant détecter des boucles événementielles asynchrones et vous empêchera d’appeler du code marqué comme non adapté à l’asynchrone (« async unsafe »), tel que des opérations avec l’ORM, à partir d’un contexte asynchrone. Si vous utilisiez précédemment Django à partir de code asynchrone, ceci pourrait vous bloquer si vous ne le faisiez pas correctement. Si vous voyez une erreur `SynchronousOnlyOperation`, examinez attentivement votre code et déplacez d’éventuelles opérations de base de données plutôt dans un fil d’exécution synchrone.

### Contraintes d’exclusion avec PostgreSQL

La nouvelle classe `ExclusionConstraint` permet d’ajouter des contraintes d’exclusion avec PostgreSQL Ces contraintes peuvent être ajoutées aux modèles en utilisant l’option `Meta.constraints`.

### Expressions de filtres

Les expressions qui produisent des résultats `BooleanField` peuvent dorénavant être directement utilisées dans des filtres `QuerySet`, sans devoir passer par une annotation préalable et un filtre sur cette annotation.

### Énumérations pour les choix de champs de modèles

Les types d’énumération personnalisés `TextChoices`, `IntegerChoices` et `Choices` sont dorénavant disponibles dans l’optique de définir `Field.choices`. Les types `TextChoices` et `IntegerChoices` sont fournis pour les champs texte et nombre entier. La classe `Choices` permet de définir une énumération compatible avec les autres types de données concrets. Ces types personnalisés prennent en charge les étiquettes conviviales pouvant être traduites et obtenues par une propriété de l’énumération ou de ses membres. Lisez Types énumératifs pour plus de détails et des exemples.

### Fonctionnalités mineures

#### `django.contrib.admin`

- La prise en charge de l’attribut `admin_order_field` pour les propriétés dans `ModelAdmin.list_display`.

- La nouvelle méthode `ModelAdmin.get_inlines()` permet de définir les sous-formulaires intégrés sur la base de la requête ou de l’instance de modèle.

- La bibliothèque Select2 a été mise à jour de la version 4.0.3 vers 4.0.7.

- La version intégrée de jQuery a été mise à jour de 3.3.1 vers 3.4.1.

#### `django.contrib.auth`

- Le nouvel attribut `reset_url_token` dans `PasswordResetConfirmView` permet de définir un paramètre jeton affiché comme composant des URL de réinitialisation de mot de passe.

- La classe `BaseBackend` a été ajoutée pour faciliter la personnalisation des moteurs d’authentification.

- Added `get_user_permissions()` method to mirror the existing `get_group_permissions()` method.

- L’attribut HTML `autocomplete` a été ajouté aux composants des champs nom d’utilisateur, courriel et mot de passe dans `django.contrib.auth.forms` pour une meilleure interaction avec les gestionnaires de mots de passe des navigateurs.

- `createsuperuser` se replie sur les variables d’environnement pour les champs mot de passe et autres champs obligatoires, lorsqu’elle ne trouve pas de paramètre correspondant sur la ligne de commande en mode non interactif.

- `REQUIRED_FIELDS` prend dorénavant en charge les champs `ManyToManyField`.

- La nouvelle méthode `UserManager.with_perm()` renvoie les utilisateurs ayant la permission indiquée.

- Le nombre d’itération par défaut du hacheur de mot de passe PBKDF2 a été augmenté de 150’000 à 180’000.

#### `django.contrib.gis`

- Les fonctions de requête spatiale MySQL opèrent dorénavant sur les géométries réelles. Précédemment, seules les boîtes englobantes étaient prises en compte.

- La fonction `GeometryDistance` a été ajoutée, prise en charge par PostGIS.

- La prise en charge de l’unité `furlong` (sillon) a été ajoutée dans `Distance`.

- Le réglage `GEOIP_PATH` accepte maintenant les chemins `pathlib.Path`.

- La classe `GeoIP2` accepte maintenant les chemins `pathlib.Path`.

#### `django.contrib.postgres`

- La nouvelle classe `RangeOperators` aide à éviter les erreurs de syntaxe dans les opérateurs SQL qui peuvent être utilisés conjointement avec `RangeField`.

- La nouvelle expression `RangeBoundary` représente les limites des intervalles.

- Les nouvelles classes `AddIndexConcurrently` et `RemoveIndexConcurrently` permettent de créer et de supprimer des index de manière concurrente avec PostgreSQL.

#### `django.contrib.sessions`

- The new `get_session_cookie_age()` method allows dynamically specifying the session cookie age.

#### `django.contrib.syndication`

- Added the `language` class attribute to the `django.contrib.syndication.views.Feed` to customize a feed language. The default value is `get_language()` instead of `LANGUAGE_CODE`.

#### Cache

- `add_never_cache_headers()` et `never_cache()` ajoutent dorénavant la directive `private` aux en-têtes `Cache-Control`.

#### Stockage de fichier

- La nouvelle méthode `Storage.get_alternative_name()` permet d’adapter l’algorithme de génération des noms de fichiers lorsque le nom d’un fichier téléversé existe déjà.

#### Formulaires

- Formsets may control the widget used when ordering forms via `can_order` by setting the `ordering_widget` attribute or overriding `get_ordering_widget`.

#### Internationalisation

- Les réglages `LANGUAGE_COOKIE_HTTPONLY`, `LANGUAGE_COOKIE_SAMESITE` et `LANGUAGE_COOKIE_SECURE` ont été ajoutés pour définir les drapeaux `HttpOnly`, `SameSite` et `Secure` sur les cookies de langue. Les valeurs par défaut de ces réglages préservent le comportement historique.

- La prise en charge des traductions en ouzbek a été ajoutée.

#### Journalisation

- Le nouveau paramètre `reporter_class` de `AdminEmailHandler` permet de fournir une sous-classe de `django.views.debug.ExceptionReporter` pour personnaliser le texte de trace d’erreur envoyé aux `ADMINS` du site lorsque `DEBUG` vaut `False`.

#### Commandes d’administration

- La nouvelle option `compilemessages --ignore` permet d’ignorer des répertoires spécifiques lors de la recherche de fichiers `.po` à compiler.

- `showmigrations --list` affiche dorénavant la date d’application lorsque `--verbosity` est de 2 ou plus.

- Avec PostgreSQL, `dbshell` prend dorénavant en charge les certificats TLS client.

- `inspectdb` sait dorénavant découvrir les champs `OneToOneField` lorsqu’une clé étrangère possède une contrainte unique ou de clé primaire.

- La nouvelle option `--skip-checks` omet l’exécution des contrôles système avant de lancer la commande.

- Les options `startapp --template` et `startproject --template` prennent maintenant en charge les gabarits stockés dans des archives XZ (`.tar.xz`, `.txz`) et LZMA (`.tar.lzma`, `.tlz`).

#### Modèles

- Les fonctions de base de données de génération d’empreintes `MD5`, `SHA1`, `SHA224`, `SHA256`, `SHA384` et `SHA512` ont été ajoutées.

- La fonction de base de données `Sign` a été ajoutée.

- Le nouveau paramètre `is_dst` des fonctions de base de données `Trunc` détermine le traitement des heures non existantes ou ambiguës.

- `connection.queries` affiche dorénavant les instructions `COPY … TO` avec PostgreSQL.

- `FilePathField` accepte dorénavant un objet exécutable pour `path`.

- Les tables intermédiaires symétriques sont permises pour les champs auto-référencés `ManyToManyField`.

- Les attributs `name` de `CheckConstraint`, `UniqueConstraint` et `Index` prennent dorénavant en charge l’interpolation de classe et d’étiquette d’application en utilisant les substituants `'%(app_label)s'` et `'%(class)s'`.

- The new `Field.descriptor_class` attribute allows model fields to customize the get and set behavior by overriding their descriptors.

- `Avg` et `Sum` acceptent dorénavant un paramètre `distinct`.

- Le champ `SmallAutoField` a été ajouté ; il est similaire à `AutoField` sauf qu’il ne permet des valeurs que jusqu’à une certaine limite (dépendante de la base de données). Les valeurs de `1` à `32767` sont valables pour toutes les bases de données prises en charge par Django.

- `AutoField`, `BigAutoField` et `SmallAutoField` héritent dorénavant respectivement de `IntegerField`, `BigIntegerField` et `SmallIntegerField`. Les contrôles système et les validateurs sont aussi correctement hérités.

- `FileField.upload_to` accepte maintenant les chemins `pathlib.Path`.

- `CheckConstraint` est dorénavant prise en charge avec MySQL 8.0.16+.

- La nouvelle méthode `allows_group_by_selected_pks_on_model()` de `django.db.backends.base.BaseDatabaseFeatures` permet d’optimiser les clauses `GROUP BY` pour n’exiger que les clés primaires des modèles sélectionnés. Par défaut, elle n’est prise en charge que pour les modèles gérés avec PostgreSQL.

  Pour activer l’optimisation de clé primaire seule pour `GROUP BY` pour les modèles non gérés (« unmanaged »), vous deez créer une sous-classe du moteur de base de données PostgreSQL, surchargeant la classe de fonctionnalité `features` avec une méthode `allows_group_by_selected_pks_on_model()` selon vos besoins. Voir l’exemple Sous-classes des moteurs de base de données intégrés.

#### Requêtes et réponses

- `HttpResponse` peut maintenant être initialisée avec du contenu `memoryview`.

- For use in, for example, Django templates, `HttpRequest.headers` now allows lookups using underscores (e.g. `user_agent`) in place of hyphens.

#### Sécurité

- La valeur par défaut de `X_FRAME_OPTIONS` est dorénavant `'DENY'`. Dans les anciennes versions, cette valeur par défaut était `'SAMEORIGIN'`. Si votre site utilise des cadres (« frames ») de lui-même, vous devrez explicitement définir `X_FRAME_OPTIONS = 'SAMEORIGIN'` pour qu’ils continuent à fonctionner.

- `SECURE_CONTENT_TYPE_NOSNIFF` now defaults to `True`. With this enabled, `SecurityMiddleware` sets the X-Content-Type-Options: nosniff header on all responses that do not already have it.

- `SecurityMiddleware` peut dorénavant envoyer l’en-tête Referrer-Policy.

#### Tests

- Le nouveau paramètre `raise_request_exception` de la classe de test `Client` permet de contrôler si les exceptions générées pendant la requête doivent être propagées dans les tests. La valeur par défaut est `True` pour des raisons de rétrocompatibilité. Quand elle vaut `False` et qu’une exception survient, le client de test renverra une réponse 500 avec l’attribut `exc_info`, un tuple fournissant des informations sur l’exception survenue.

- Les tests et les cas de tests à lancer peuvent être choisis par un motif de nom de test à l’aide de la nouvelle option `test -k`.

- La comparaison HTML, telle qu’utilisée par `assertHTMLEqual()` traite dorénavant le texte, les références de caractères et les références d’entité qui se réfèrent au même caractère comme équivalents.

- `DiscoverRunner` can now spawn a debugger at each error or failure using the `test --pdb` option.

## Changements incompatibles avec les anciennes versions dans Django 3.0

### `Model.save()` when providing a default for the primary key

`Model.save()` no longer attempts to find a row when saving a new `Model` instance and a default value for the primary key is provided, and always performs a single `INSERT` query. In older Django versions, `Model.save()` performed either an `INSERT` or an `UPDATE` based on whether or not the row exists.

This makes calling `Model.save()` while providing a default primary key value equivalent to passing force_insert=True to model’s `save()`. Attempts to use a new `Model` instance to update an existing row will result in an `IntegrityError`.

In order to update an existing model for a specific primary key value, use the `update_or_create()` method or `QuerySet.filter(pk=…).update(…)` instead. For example:

    >>> MyModel.objects.update_or_create(pk=existing_pk, defaults={"name": "new name"})
    >>> MyModel.objects.filter(pk=existing_pk).update(name="new name")

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

- Le second paramètre de `DatabaseIntrospection.get_geometry_type()` est dorénavant la description de la ligne au lieu du nom de la colonne.

- `DatabaseIntrospection.get_field_type()` ne renvoie plus forcément des tuples.

- Si une base de données peut créer des clés étrangères dans la même instruction SQL qui ajoute un champ, ajoutez l’attribut `SchemaEditor.sql_create_column_inline_fk` à son moteur, avec le contenu SQL approprié ; sinon, définissez `DatabaseFeatures.can_create_inline_fk = False`.

- `DatabaseFeatures.can_return_id_from_insert` et `can_return_ids_from_bulk_insert` sont renommés en `can_return_columns_from_insert` et `can_return_rows_from_bulk_insert`.

- Les fonctions de base de données prennent maintenant en charge les formats `datetime.timezone` lorsqu’elles sont créées avec des instances `datetime.timedelta` (par ex. `timezone(timedelta(hours=5))`, qui produirait `'UTC+05:00'`). Les moteurs tiers doivent prendre en compte ce format lors de la préparation de `DateTimeField` dans `datetime_cast_date_sql()`, `datetime_extract_sql()`, etc.

- Des lignes sont ajoutées à `DatabaseOperations.integer_field_ranges` pour les champs `AutoField`, `BigAutoField` et `SmallAutoField` afin de prendre en charge les validateurs d’intervalles de nombres entiers pour ces types de champ. Les moteurs tiers pourraient avoir à adapter les lignes par défaut.

- `DatabaseOperations.fetch_returned_insert_id()` est remplacée par `fetch_returned_insert_columns()` qui renvoie une liste de valeurs renvoyées par l’instruction `INSERT … RETURNING` au lieu d’une valeur unique.

- `DatabaseOperations.return_insert_id()` est remplacée par `return_insert_columns()` qui accepte un paramètre `fields` qui est un itérable de champs à renvoyer après l’insertion. Généralement, il ne s’agit que du champ clé primaire auto-généré.

### `django.contrib.admin`

- Les messages de changement des historiques de modèle du site d’administration préfèrent dorénavant les étiquettes de champ plus lisibles plutôt que les noms de champ.

### `django.contrib.gis`

- La prise en charge de PostGIS 2.1 a été supprimée.

- La prise en charge de SpatiaLite 4.1 et 4.2 a été supprimée.

- La prise en charge de GDAL 1.11 et GEOS 3.4 a été supprimée.

### Abandon de la prise en charge de PostgreSQL 9.4

La prise en charge amont de PostgreSQL 9.4 se termine en décembre 2019. Django 3.0 prend en charge PostgreSQL 9.5 et plus récent.

### Abandon de la prise en charge de Oracle 12.1

La prise en charge de Oracle 12.1 par le projet amont se termine en juillet 2021. Django 2.2 sera pris en charge jusqu’en avril 2022. Django 3.0 prend officiellement en charge Oracle 12.2 et 18c.

### Les API de compatibilité privées de Python 2 ont été supprimées.

Bien que la prise en charge de Python 2 ait été supprimée dans Django 2.0, certaines API privées n’ont pas été supprimées de Django afin que des applications tierces puissent continuer à les utiliser jusqu’à la fin de vie de Python 2.

Comme nous nous attendons à ce que les applications abandonnent la compatibilité avec Python 2 lors de l’ajout de la prise en charge de Django 3.0, nous supprimons ces API dans cette version.

- `django.test.utils.str_prefix()` - Les chaînes n’ont plus de préfixe « u » avec Python 3.

- `django.test.utils.patch_logger()` - Utilisez `unittest.TestCase.assertLogs()` à la place.

- `django.utils.lru_cache.lru_cache()` - Alias de `functools.lru_cache()`.

- `django.utils.decorators.available_attrs()` - Cette fonction renvoie `functools.WRAPPER_ASSIGNMENTS`.

- `django.utils.decorators.ContextDecorator` - Alias de `contextlib.ContextDecorator`.

- `django.utils._os.abspathu()` - Alias de `os.path.abspath()`.

- `django.utils._os.upath()` et `npath()` - Ces fonctions ne font plus rien en Python 3.

- `django.utils.six` - Remove usage of this vendored library or switch to six.

- `django.utils.encoding.python_2_unicode_compatible()` - Alias de `six.python_2_unicode_compatible()`.

- `django.utils.functional.curry()` - Use `functools.partial()` or `functools.partialmethod`. See 5b1c389603a353625ae1603ba345147356336afb.

- `django.utils.safestring.SafeBytes` - Inutilisée depuis Django 2.0.

### Nouvelle valeur par défaut du réglage `FILE_UPLOAD_PERMISSIONS`

Dans les versions précédentes, le réglage `FILE_UPLOAD_PERMISSIONS` valait `None` par défaut. Avec le gestionnaire par défaut `FILE_UPLOAD_HANDLERS`, cela pouvait aboutir à des fichiers téléversés ayant des permissions différentes dépendant de leur taille et donc de quel gestionnaire de téléversement était utilisé.

`FILE_UPLOAD_PERMISSIONS` now defaults to `0o644` to avoid this inconsistency.

### Nouvelles valeurs par défaut de réglages de sécurité

Pour rendre les projets Django plus sûrs par défaut, certains réglages de sécurité ont dorénavant des valeurs par défaut plus sûres :

- La nouvelle valeur par défaut de `X_FRAME_OPTIONS` est `'DENY'`.

- La nouvelle valeur par défaut de `SECURE_CONTENT_TYPE_NOSNIFF` est `True`.

Consultez la section sécurité des nouveautés de Django 3.0 pour plus de détails sur ces changements.

### Divers

- `ContentType.__str__()` inclut dorénavant l’étiquette `app_label` de son modèle pour distinguer les modèles ayant le même nom dans des applications différentes.

- Comme l’accès à la langue dans la session a été rendu obsolète au profit des cookies, `LocaleMiddleware` ne cherche plus la langue de l’utilisateur dans la session et `django.contrib.auth.logout()` ne préserve plus la langue de la session après la déconnexion.

- `django.utils.html.escape()` utilise dorénavant `html.escape()` pour l’échappement du code HTML. Le guillemet simple `'` est dorénavant converti en `&#x27;` au lieu de l’équivalent en format décimal `&#39;`.

- L’option `django-admin test -k` fonctionne dorénavant comme l’option `unittest -k` plutôt que comme un raccourci de `--keepdb`.

- La prise en charge de `pywatchman` < 1.2.0 a été abandonnée.

- `urlencode()` code dorénavant les valeurs itérables telles qu’elles sont lorsque `doseq=False`, plutôt que de les passer en boucle, ce qui rapproche du comportement de la fonction de bibliothèque standard `urllib.parse.urlencode()`.

- Le filtre de gabarit `intword` traduit dorénavant `1.0` avec une phrase au singulier et toutes les autres valeurs numériques comme une phrase au pluriel, ce qui n’est pas toujours correct selon les langues.

- Assigning a value to a model’s `ForeignKey` or `OneToOneField` `'_id'` attribute now unsets the corresponding field. Accessing the field afterward will result in a query.

- `patch_vary_headers()` traite dorénavant l’astérisque `'*'` en accord avec la RFC 7231 Section 7.1.4, c’est-à-dire que si une liste de noms de champs d’en-tête contient un astérisque, l’en-tête `Vary` sera formé d’un seul astérisque `'*'`.

- Avec MySQL 8.0.16+, `PositiveIntegerField` et `PositiveSmallIntegerField` incluent dorénavant une contrainte de contrôle pour empêcher les valeurs négatives dans la base de données.

- `alias=None` a été ajouté à la signature de `Expression.get_group_by_cols()`.

- `RegexPattern`, used by `re_path()`, no longer returns keyword arguments with `None` values to be passed to the view for the optional named groups that are missing.

## Fonctionnalités rendues obsolètes dans Django 3.0

### `django.utils.encoding.force_text()` et `smart_text()`

Les alias `smart_text()` et `force_text()` (depuis Django 2.0) de `smart_str()` et `force_str()` sont rendus obsolètes. Vous pouvez ignorer l’avertissement si votre code prend en charge Python 2 car le comportement de `smart_str()` et `force_str()` est différent dans ce contexte.

### Divers

- `django.utils.http.urlquote()`, `urlquote_plus()`, `urlunquote()` et `urlunquote_plus()` sont rendus obsolètes en faveur des fonctions pour lesquelles elles sont des alias : `urllib.parse.quote()`, `quote_plus()`, `unquote()` et `unquote_plus()`.

- `django.utils.translation.ugettext()`, `ugettext_lazy()`, `ugettext_noop()`, `ungettext()` et `ungettext_lazy()` sont rendues obsolètes en faveur des fonctions pour lesquelles elles sont des alias : `django.utils.translation.gettext()`, `gettext_lazy()`, `gettext_noop()`, `ngettext()` et `ngettext_lazy()`.

- Afin de limiter la création de sessions et donc de favorise certaines stratégies de cache, `django.views.i18n.set_language()` arrêtera de définir la langue de l’utilisateur dans la session à partir de Django 4.0. Dès Django 2.1, la langue est toujours stockée dans le cookie `LANGUAGE_COOKIE_NAME`.

- `django.utils.text.unescape_entities()` est rendu obsolète en faveur de `html.unescape()`. Notez qu’au contraire de `unescape_entities()`, `html.unescape()` évalue immédiatement les chaînes différées.

- Pour éviter une possible confusion sur sa portée réelle, l’utilitaire interne privé `is_safe_url()` a été renommé en `url_has_allowed_host_and_scheme()`. Le fait que le protocole et l’hôte d’une URL soit autorisés n’implique en général pas qu’elle soit sûre. Elle pourrait par exemple être codée de façon incorrecte. Assurez-vous d’appliquer aussi `iri_to_uri()` sur la partie chemin des URL de source non fiable.

## Fonctionnalités supprimées dans 3.0

Ces fonctionnalités ont atteint la fin de leur cycle d’obsolescence et sont supprimées dans Django 3.0.

Voir Features deprecated in 2.0 pour les détails de ces changements, ainsi que pour savoir comment supprimer l’utilisation de ces fonctionnalités.

- Le module `django.db.backends.postgresql_psycopg2` a été supprimé.

- `django.shortcuts.render_to_response()` a été supprimée.

- Le réglage `DEFAULT_CONTENT_TYPE` a été supprimé.

- `HttpRequest.xreadlines()` a été supprimée.

- La prise en charge du paramètre `context` de `Field.from_db_value()` et de `Expression.convert_value()` a été supprimée.

- Le paramètre nommé `field_name` de `QuerySet.earliest()` et de `latest()` a été supprimé.

Voir Fonctionnalités rendues obsolètes dans Django 2.1 pour les détails de ces changements, ainsi que pour savoir comment supprimer l’utilisation de ces fonctionnalités.

- La fonction SIG `ForceRHR` a été supprimée.

- `django.utils.http.cookie_date()` a été supprimée.

- Les bibliothèques de balises de gabarits `staticfiles` et `admin_static` ont été supprimées.

- `django.contrib.staticfiles.templatetags.staticfiles.static()` a été supprimée.