Notes de publication de Django 2.2¶
1er avril 2019
Bienvenue dans Django 2.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 2.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 2.2 is designated as a long-term support release. It will receive security updates for at least three years after its release. Support for the previous LTS, Django 1.11, will end in April 2020.
Compatibilité Python¶
Django 2.2 supports Python 3.5, 3.6, 3.7, 3.8 (as of 2.2.8), and 3.9 (as of 2.2.17). We highly recommend and only officially support the latest release of each series.
Quoi de neuf dans Django 2.2¶
Contraintes¶
Les nouvelles classes class:~django.db.models.CheckConstraint and UniqueConstraint permettent d’ajouter des contraintes de base de données personnalisées. Ces contraintes peuvent être ajoutées aux modèles en utilisant l’option Meta.constraints.
Fonctionnalités mineures¶
django.contrib.admin¶
Une classe CSS a été ajoutée aux en-têtes de colonnes de
TabularInline.
django.contrib.auth¶
La requête
HttpRequestest dorénavant transmise comme premier paramètre positionnel àRemoteUserBackend.configure_user(), si celle-ci l’accepte.
django.contrib.gis¶
django.contrib.postgres¶
Le nouveau paramètre
orderingdeArrayAggetStringAggdétermine l’ordre des éléments agrégés.Les nouvelles classes
BTreeIndex,HashIndexetSpGistIndexpermettent de créer des indexB-Tree,hashetSP-GiSTdans la base de données.BrinIndexpossède maintenant le paramètreautosummarize.Le nouveau paramètre
search_typedeSearchQuerypermet de rechercher une phrase ou une expression brute.
django.contrib.staticfiles¶
La correspondance de chemins a été ajoutée à l’option
collectstatic --ignoreafin de pouvoir utiliser des motifs du genre/vendor/*.js.
Moteurs de base de données¶
Avec SQLite, la diffusion en flux des résultats a été ajoutée pour
QuerySet.iterator().
Vues génériques¶
The new
View.setuphook initializes view attributes before callingdispatch(). It allows mixins to set up instance attributes for reuse in child classes.
Internationalisation¶
La prise en charge des traductions en arménien a été ajoutée.
Commandes d’administration¶
La nouvelle option option:–force-color force la coloration des résultats de commandes.
inspectdbcrée dorénavant des modèles pour les tables étrangères avec PostgreSQL.inspectdb --include-viewscrée dorénavant des modèles pour les vues matérialisées avec Oracle et PostgreSQL.La nouvelle option
inspectdb --include-partitionspermet de créer des modèles pour les tables de partitions avec PostgreSQL. Dans les versions précédentes, les modèles étaient créés comme tables enfants au lieu de parents.inspectdbsait dorénavant découvrir les champsDurationFieldavec Oracle et PostgreSQL, ainsi que les champsAutoFieldavec SQLite.Avec Oracle,
dbshellest envelopéé dansrlwrap, si disponible.rlwrapfournit un historique des commandes et permet d’éditer les saisies au clavier.La nouvelle option
makemigrations --no-headerpermet d’éviter les commentaires en en-tête dans les fichiers de migration générés. Cette option est aussi disponible poursquashmigrations.runserverpeut dorénavant exploiter Watchman pour améliorer les performances lors de la surveillance de modification pour de nombreux fichiers.
Migrations¶
La nouvelle option
migrate --planimprime la liste des opérations de migration qui seront effectuées.NoneTypepeut maintenant être sérialisé dans les migrations.Il est maintenant possible d”inscrire des sérialiseurs personnalisés pour les migrations.
Modèles¶
La prise en charge des opérateurs de classes PostgreSQL (
Index.opclasses) a été ajoutée.La prise en charge des index partiels (
Index.condition) a été ajoutée.Les fonctions de base de données class:~django.db.models.functions.NullIf et
Reverseont été ajoutées, de même que de nombreuses fonctions de base de données mathématiques.La définition du nouveau paramètre
ignore_conflictsdeQuerySet.bulk_create()àTrueindique à la base de données d’ignorer les insertions de lignes qui ne passent pas les contrôles d’unicité et autres contrôles.La nouvelle fonction
ExtractIsoYearextrait les années avec numéro de semaine ISO-8601 des champsDateFieldetDateTimeField, et la nouvelle expression de requêteiso_yearpermet d’interroger selon une année avec numéro de semaine ISO-8601.La nouvelle méthode
QuerySet.bulk_update()permet de mettre à jour efficacement des champs spécifiques sur plusieurs instances de modèles.Django ne démarre plus automatiquement une transaction lors de l’exécution d’une seule requête, telle que
Model.save(),QuerySet.update()etModel.delete(). Cela améliore la performance en mode commit automatique en diminuant le nombre d’aller-retour vers la base de données.La prise en charge des fonctions
StdDevetVariancea été ajoutée pour SQLite.La gestion des agrégats avec
DISTINCTa été ajoutée à la classeAggregate. La définition deallow_distinct = Truecomme attribut de classe sur des sous-classes deAggregatepermet d’indiquer un paramètre nommédistinctlors de l’initialisation pour s’assurer que la fonction d’agrégat n’est appelée que pour chaque valeur distincte deexpressions.Les méthodes
RelatedManager.add(),create(),remove(),set(),get_or_create()etupdate_or_create()sont dorénavant autorisées sur des relations plusieurs-à-plusieurs avec modèle intermédiaire. Le nouveau paramètrethrough_defaultsest utilisé pour indiquer des valeurs à définir sur la ou les instances de modèle intermédiaire.
Requêtes et réponses¶
L’attribut
HttpRequest.headersa été ajouté pour permettre un accès simplifié aux en-têtes de requêtes.
Sérialisation¶
Il est dorénavant possible de désérialiser des données en utilisant des clés naturelles contenant des références en aval en passant
handle_forward_references=Trueàserializers.deserialize(). De plus,loaddatagère automatiquement les références en aval.
Tests¶
La nouvelle assertion
SimpleTestCase.assertURLEqual()vérifie l’égalité avec une URL donnée en ignorant l’ordre des paramètres de la chaîne de requête.assertRedirects()utilise cette nouvelle assertion.Le client de test
Clientprend dorénavant en charge automatiquement la sérialisation JSON des listes et tuplesdatalorsquecontent_type='application/json'.Le nouveau réglage de base de données de test
ORACLE_MANAGED_FILESpermet d’utiliser des espaces de tables Oracle Managed Files (OMF).Les contraintes de base de données différables sont dorénavant appliquées à la fin de chaque test
TestCaseavec SQLite 3.20+, tout comme c’est déjà le cas pour les autres moteurs qui prennent en charge ce type de contraintes. Ces contrôles ne sont pas appliqués pour les versions plus anciennes de SQLite car ils nécessiteraient de coûteuses introspections de tables.DiscoverRunnerne configure plus les bases de données qui ne sont pas référencées par les tests.
URL¶
Le nouvel attribut
ResolverMatch.routestocke la route du motif d’URL correspondant.
Validateurs¶
MaxValueValidator,MinValueValidator,MinLengthValidatoretMaxLengthValidatoracceptent maintenant une valeurlimit_valueexécutable.
Changements incompatibles avec les anciennes versions dans Django 2.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.
Les moteurs de base de données de tierce-partie doivent implémenter la prise en charge des contraintes de vérification sur les tables ou définir
DatabaseFeatures.supports_table_check_constraintsàFalse.Les moteurs de base de données de tierce-partie doivent implémenter la capacité d’ignorer les contraintes ou erreurs d’unicité lors d’insertions, ou définir
DatabaseFeatures.supports_ignore_conflictsàFalse.Les moteurs de base de données de tierce-partie doivent implémenter l’introspection pour
DurationFieldou définirDatabaseFeatures.can_introspect_duration_fieldàFalse.DatabaseFeatures.uses_savepointsvaut dorénavantTruepar défaut.Les moteurs de base de données de tierce-partie doivent implémenter la prise en charge des index partiels ou définir
DatabaseFeatures.supports_partial_indexesàFalse.DatabaseIntrospection.table_name_converter()etcolumn_name_converter()ont été supprimées. Les moteurs de base de données de tierce-partie peuvent devoir implémenterDatabaseIntrospection.identifier_converter()à la place. Dans ce cas, les noms de contraintes renvoyés parDatabaseIntrospection.get_constraints()doivent être normalisés paridentifier_converter().La génération SQL des index a été déplacée de
IndexversSchemaEditoret ces méthodes deSchemaEditoront été ajoutées :_create_primary_key_sql()et_delete_primary_key_sql()_delete_index_sql()(en réponse à_create_index_sql())_delete_unique_sql(en réponse à_create_unique_sql())_delete_fk_sql()(en réponse à_create_fk_sql())_create_check_sql()et_delete_check_sql()
Le troisième paramètre de
DatabaseWrapper.__init__(),allow_thread_sharing, a été supprimé.
Les actions d’administration ne sont plus collectées à partir des classes ModelAdmin de base¶
Par exemple, dans les anciennes versions de Django
from django.contrib import admin
class BaseAdmin(admin.ModelAdmin):
actions = ["a"]
class SubAdmin(BaseAdmin):
actions = ["b"]
SubAdmin disposait des actions 'a' et 'b'.
Dorénavant les actions suivent l’héritage Python standard. Pour obtenir le même résultat qu’auparavant
class SubAdmin(BaseAdmin):
actions = BaseAdmin.actions + ["b"]
django.contrib.gis¶
La prise en charge de GDAL 1.9 et 1.10 a été abandonnée.
Chargement de données TransactionTestCase sérialisées¶
Les migrations de données initiales sont dorénavant chargées dans TransactionTestCase à la fin du test, après la réinitialisation de la base de données. Dans les anciennes versions, ces données étaient chargées au début du test mais cela perturbait le fonctionnement de l’option test --keepdb (la base de données était vide à la fin de tous les tests). Cette modification ne devrait pas avoir d’impacts sur vos tests pour autant que vous n’avez pas personnalisé le fonctionnement interne de TransactionTestCase.
sqlparse devient une dépendance obligatoire¶
To simplify a few parts of Django’s database handling, sqlparse 0.2.2+ is now a required dependency. It’s automatically installed along with Django.
Alias de cached_property¶
Dans les utilisations telles que
from django.utils.functional import cached_property
class A:
@cached_property
def base(self):
return ...
alias = base
alias n’est pas mis en cache. Là où le problème peut être détecté (Python à partir de 3.6), une telle utilisation produit maintenant une exception TypeError: Cannot assign the same cached_property to two different names ('base' and 'alias').
Utilisez plutôt ceci
import operator
class A:
...
alias = property(operator.attrgetter("base"))
Permissions pour les modèles mandataires¶
Les permissions pour les modèles mandataires sont dorénavant créées en utilisant le type de contenu du modèle mandataire plutôt que celui de leur modèle concret. Une migration va mettre à jour les permissions existantes lors de l’exécution de migrate.
Dans le site d’administration, la modification est transparente pour les modèles mandataires ayant la même étiquette app_label que leur modèle concret. Cependant, dans les anciennes versions, les utilisateurs ayant des permissions pour un modèle mandataire avec une étiquette app_label différente de celle du modèle concret n’avaient pas accès au modèle dans le site d’administration. Ceci est maintenant résolu, mais il peut valoir la peine d’auditer les attributions de permissions pour les modèles concernés ([add|view|change|delete]_monmandataire) avant la mise à jour pour être certain que les nouveaux accès soient corrects.
Pour terminer, les chaînes de permission des modèles mandataires doivent être mises à jour afin d’utiliser leur propre étiquette app_label. Par exemple, pour app.MonModeleMandataire héritant de autre_app.ModeleConcret, mettez à jour user.has_perm('autre_app.add_monmodelemandataire') en user.has_perm('app.add_monmodelemandataire').
Fusion des fichiers statiques Media des formulaires¶
Les fichiers statiques Media des formulaires sont dorénavant fusionnés en utilisant un algorithme de tri topologique, car l’ancien algorithme de fusion par paires était insuffisant à certains égards. Les fichiers CSS et JavaScript qui n’incluent pas leurs dépendances pourraient maintenant être triées de manière incorrecte (là où l’ancien algorithme aurait produit un résultat correct par coïncidence).
Auditer chaque classe Media à la recherche de dépendances manquantes. Par exemple, les composants dépendants de django.jQuery doivent indiquer js=['admin/js/jquery.init.js', ...] dans la déclaration des fichiers statiques de formulaires.
Divers¶
Pour améliorer la lisibilité, le champ de formulaire
UUIDFieldaffiche dorénavant les valeurs avec tirets, par exemple550e8400-e29b-41d4-a716-446655440000au lieu de550e8400e29b41d4a716446655440000.Avec SQLite,
PositiveIntegerFieldetPositiveSmallIntegerFieldincluent dorénavant une contrainte de vérification pour éviter des valeurs négatives dans la base de données. Si des données non valides existent actuellement et que vous lancez une migration qui recrée une table, vous verrez apparaître des erreurs du typeCHECK constraint failed.Par cohérence avec les serveurs WSGI, le client de test définit dorénavant l’en-tête
Content-Lengthcomme chaîne au lieu de nombre entier.La valeur de renvoi de
django.utils.text.slugify()n’est plus marquée comme HTML sécurisé.Le caractère de troncature par défaut utilisé par les filtres de gabarit
urlizetrunc,truncatechars,truncatechars_html,truncatewordsettruncatewords_htmlest désormais le caractère « points de suspension » réel (…) au lieu de 3 points. Il se peut que vous deviez mettre à jour certaines comparaisons dans les résultats de tests.La prise en charge des chemins d’octets dans le chargeur de gabarits depuis le système de fichiers a été supprimée.
django.utils.http.urlsafe_base64_encode()renvoie dorénavant une chaîne au lieu d’une chaîne d’octets, etdjango.utils.http.urlsafe_base64_decode()n’accepte plus une chaîne d’octets en paramètre.La prise en charge de
cx_Oracle< 6.0 a été abandonnée.La version minimum de
mysqlclientprise en charge est passée de 1.3.7 à 1.3.13.La version minimum de SQLite prise en charge est passée de 3.7.15 à 3.8.3.
Dans le but de fournir des données de requêtes un peu plus sémantiques,
NullBooleanSelectproduit dorénavant les valeurs d”<option>unknown,trueetfalseau lieu de1,2et3. Par rétrocompatibilité, les données avec les anciennes valeurs sont toujours acceptées.La longueur maximale
max_lengthdeGroup.namea passé de 80 à 150 caractères.Les tests qui violent les contraintes de base de données différables produisent dorénavant des erreurs avec SQLite 3.20+, tout comme avec les autres moteurs qui gèrent aussi ces contraintes.
Pour intercepter les erreurs d’utilisation, le client de test
Clientainsi quedjango.utils.http.urlencode()génèrent maintenant une exceptionTypeErrorsiNoneest transmis comme valeur à coder, carNonene peut pas être codé dans les données GET et POST. Transmettez plutôt une chaîne vide, ou omettez entièrement la valeur.The
ping_googlemanagement command now defaults tohttpsinstead ofhttpfor the sitemap’s URL. If your site uses http, use the newping_google --sitemap-uses-httpoption. If you use thedjango.contrib.sitemaps.ping_googlefunction, set the newsitemap_uses_httpsargument toFalse.runserverno longer supportspyinotify(replaced by Watchman).Les fonctions d’agrégat
Avg,StdDevetVariancerenvoient dorénavant un nombreDecimalau lieu d’unfloatsi la valeur d’entrée est un nombreDecimal.Les tests échoueront avec SQLite si les applications sans migrations ont des relations à des applications avec migrations. Ceci a toujours été une limitation documentée depuis l’introduction des migrations dans Django 1.7, mais les échecs sont désormais plus constants. Vous verrez des tests échouant avec des erreurs comme
no such table: <app_label>_<model>. Cela s’est produit dans plusieurs applications tierces qui ont des modèles sans migrations dans leurs tests. Vous devez ajouter des migrations pour de tel modèles.Providing an integer in the
keyargument of thecache.delete()orcache.get()now raisesValueError.Plural equations for some languages are changed, because the latest versions from Transifex are incorporated.
Note
The ability to handle
.pofiles containing different plural equations for the same language was added in Django 2.2.12.
Fonctionnalités rendues obsolètes dans Django 2.2¶
L’attribut Meta.ordering des modèles n’affectera plus les requêtes de type GROUP BY¶
L’attribut Meta.ordering d’un modèle affectant les requêtes GROUP BY (telles que .annotate().values()) est une source fréquente de confusion. De telles requêtes émettent dorénavant un avertissement d’obsolescence avec le conseil d’ajouter order_by() pour conserver le comportement existant de la requête. Meta.ordering sera ignoré dans ces requêtes à partir de Django 3.1.
Divers¶
django.utils.timezone.FixedOffseta été rendu obsolète en faveur dedatetime.timezone.L’alias non documenté
QuerySetPaginatordedjango.core.paginator.Paginatora été rendu obsolète.Le champ de modèle et de formulaire
FloatRangeFielddansdjango.contrib.postgresa été rendu obsolète en faveur d’un nouveau nom,DecimalRangeField, pour mieux refléter le type de donnéesnumrangeutilisé au niveau de la base de données.Le réglage
FILE_CHARSETest obsolète. À partir de Django 3.1, les fichiers lus depuis le disque doivent être codés en UTF-8.django.contrib.staticfiles.storage.CachedStaticFilesStoragea été rendu obsolète en raison de ses problèmes insolubles. Remplacez-le plutôt parManifestStaticFilesStorageou un stockage en nuage de tierce partie.RemoteUserBackend.configure_user()reçoit dorénavantrequestcomme premier paramètre positionnel, s’il l’accepte. La prise en charge des méthodes surchargées n’acceptant pas ce paramètre sera supprimée dans Django 3.1.The
SimpleTestCase.allow_database_queries,TransactionTestCase.multi_db, andTestCase.multi_dbattributes are deprecated in favor ofSimpleTestCase.databases,TransactionTestCase.databases, andTestCase.databases. These new attributes allow databases dependencies to be declared in order to prevent unexpected queries against non-default databases to leak state between tests. The previous behavior ofallow_database_queries=Trueandmulti_db=Truecan be achieved by settingdatabases='__all__'.