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 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
HttpRequest
est dorénavant transmise comme premier paramètre positionnel àRemoteUserBackend.configure_user()
, si celle-ci l’accepte.
django.contrib.postgres
¶
- Le nouveau paramètre
ordering
deArrayAgg
etStringAgg
détermine l’ordre des éléments agrégés. - Les nouvelles classes
BTreeIndex
,HashIndex
etSpGistIndex
permettent de créer des indexB-Tree
,hash
etSP-GiST
dans la base de données. BrinIndex
possède maintenant le paramètreautosummarize
.- Le nouveau paramètre
search_type
deSearchQuery
permet de rechercher une phrase ou une expression brute.
django.contrib.staticfiles
¶
- La correspondance de chemins a été ajoutée à l’option
collectstatic --ignore
afin 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.setup
hook 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.
inspectdb
crée dorénavant des modèles pour les tables étrangères avec PostgreSQL.inspectdb --include-views
crée dorénavant des modèles pour les vues matérialisées avec Oracle et PostgreSQL.- La nouvelle option
inspectdb --include-partitions
permet 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. inspectdb
sait dorénavant découvrir les champsDurationField
avec Oracle et PostgreSQL, ainsi que les champsAutoField
avec SQLite.- Avec Oracle,
dbshell
est envelopéé dansrlwrap
, si disponible.rlwrap
fournit un historique des commandes et permet d’éditer les saisies au clavier. - La nouvelle option
makemigrations --no-header
permet d’éviter les commentaires en en-tête dans les fichiers de migration générés. Cette option est aussi disponible poursquashmigrations
. runserver
peut dorénavant exploiter Watchman pour améliorer les performances lors de la surveillance de modification pour de nombreux fichiers.
Migrations¶
- La nouvelle option
migrate --plan
imprime la liste des opérations de migration qui seront effectuées. NoneType
peut 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
Reverse
ont é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_conflicts
deQuerySet.bulk_create()
àTrue
indique à 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
ExtractIsoYear
extrait les années avec numéro de semaine ISO-8601 des champsDateField
etDateTimeField
, et la nouvelle expression de requêteiso_year
permet 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
StdDev
etVariance
a été ajoutée pour SQLite. - La gestion des agrégats avec
DISTINCT
a été ajoutée à la classeAggregate
. La définition deallow_distinct = True
comme attribut de classe sur des sous-classes deAggregate
permet d’indiquer un paramètre nommédistinct
lors 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_defaults
est 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.headers
a é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,loaddata
gè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
Client
prend dorénavant en charge automatiquement la sérialisation JSON des listes et tuplesdata
lorsquecontent_type='application/json'
. - Le nouveau réglage de base de données de test
ORACLE_MANAGED_FILES
permet 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
TestCase
avec 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. DiscoverRunner
ne configure plus les bases de données qui ne sont pas référencées par les tests.
URL¶
- Le nouvel attribut
ResolverMatch.route
stocke la route du motif d’URL correspondant.
Validateurs¶
MaxValueValidator
,MinValueValidator
,MinLengthValidator
etMaxLengthValidator
acceptent maintenant une valeurlimit_value
exé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
DurationField
ou définirDatabaseFeatures.can_introspect_duration_field
àFalse
. DatabaseFeatures.uses_savepoints
vaut dorénavantTrue
par 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
Index
versSchemaEditor
et ces méthodes deSchemaEditor
ont é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
UUIDField
affiche dorénavant les valeurs avec tirets, par exemple550e8400-e29b-41d4-a716-446655440000
au lieu de550e8400e29b41d4a716446655440000
.Avec SQLite,
PositiveIntegerField
etPositiveSmallIntegerField
incluent 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-Length
comme 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
,truncatewords
ettruncatewords_html
est 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
mysqlclient
prise 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,
NullBooleanSelect
produit dorénavant les valeurs d”<option>
unknown
,true
etfalse
au lieu de1
,2
et3
. Par rétrocompatibilité, les données avec les anciennes valeurs sont toujours acceptées.La longueur maximale
max_length
deGroup.name
a 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
Client
ainsi quedjango.utils.http.urlencode()
génèrent maintenant une exceptionTypeError
siNone
est transmis comme valeur à coder, carNone
ne 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_google
management command now defaults tohttps
instead ofhttp
for the sitemap’s URL. If your site uses http, use the newping_google --sitemap-uses-http
option. If you use thedjango.contrib.sitemaps.ping_google
function, set the newsitemap_uses_https
argument toFalse
.runserver
no longer supportspyinotify
(replaced by Watchman).Les fonctions d’agrégat
Avg
,StdDev
etVariance
renvoient dorénavant un nombreDecimal
au lieu d’unfloat
si 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
key
argument 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
.po
files 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.FixedOffset
a été rendu obsolète en faveur dedatetime.timezone
.- L’alias non documenté
QuerySetPaginator
dedjango.core.paginator.Paginator
a été rendu obsolète. - Le champ de modèle et de formulaire
FloatRangeField
dansdjango.contrib.postgres
a été rendu obsolète en faveur d’un nouveau nom,DecimalRangeField
, pour mieux refléter le type de donnéesnumrange
utilisé au niveau de la base de données. - Le réglage
FILE_CHARSET
est obsolète. À partir de Django 3.1, les fichiers lus depuis le disque doivent être codés en UTF-8. django.contrib.staticfiles.storage.CachedStaticFilesStorage
a été rendu obsolète en raison de ses problèmes insolubles. Remplacez-le plutôt parManifestStaticFilesStorage
ou un stockage en nuage de tierce partie.RemoteUserBackend.configure_user()
reçoit dorénavantrequest
comme 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_db
attributes 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=True
andmulti_db=True
can be achieved by settingdatabases='__all__'
.