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.
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.
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
.
django.contrib.admin
¶TabularInline
.django.contrib.auth
¶HttpRequest
est dorénavant transmise comme premier paramètre positionnel à RemoteUserBackend.configure_user()
, si celle-ci l’accepte.django.contrib.postgres
¶ordering
de ArrayAgg
et StringAgg
détermine l’ordre des éléments agrégés.BTreeIndex
, HashIndex
et SpGistIndex
permettent de créer des index B-Tree
, hash
et SP-GiST
dans la base de données.BrinIndex
possède maintenant le paramètre autosummarize
.search_type
de SearchQuery
permet de rechercher une phrase ou une expression brute.django.contrib.staticfiles
¶collectstatic --ignore
afin de pouvoir utiliser des motifs du genre /vendor/*.js
.QuerySet.iterator()
.View.setup
initialise les attributs des vues avant d’appeler dispatch()
. Cela permet aux classes mixin de configurer les attributs d’instance pour une réutilisation dans les classes enfants.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.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 champs DurationField
avec Oracle et PostgreSQL, ainsi que les champs AutoField
avec SQLite.dbshell
est envelopéé dans rlwrap
, si disponible. rlwrap
fournit un historique des commandes et permet d’éditer les saisies au clavier.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 pour squashmigrations
.runserver
peut dorénavant exploiter Watchman pour améliorer les performances lors de la surveillance de modification pour de nombreux fichiers.migrate --plan
imprime la liste des opérations de migration qui seront effectuées.NoneType
peut maintenant être sérialisé dans les migrations.Index.opclasses
) a été ajoutée.Index.condition
) a été ajoutée.Reverse
ont été ajoutées, de même que de nombreuses fonctions de base de données mathématiques.ignore_conflicts
de QuerySet.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.ExtractIsoYear
extrait les années avec numéro de semaine ISO-8601 des champs DateField
et DateTimeField
, et la nouvelle expression de requête iso_year
permet d’interroger selon une année avec numéro de semaine ISO-8601.QuerySet.bulk_update()
permet de mettre à jour efficacement des champs spécifiques sur plusieurs instances de modèles.Model.save()
, QuerySet.update()
et Model.delete()
. Cela améliore la performance en mode commit automatique en diminuant le nombre d’aller-retour vers la base de données.StdDev
et Variance
a été ajoutée pour SQLite.DISTINCT
a été ajoutée à la classe Aggregate
. La définition de allow_distinct = True
comme attribut de classe sur des sous-classes de Aggregate
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 de expressions
.RelatedManager.add()
, create()
, remove()
, set()
, get_or_create()
et update_or_create()
sont dorénavant autorisées sur des relations plusieurs-à-plusieurs avec modèle intermédiaire. Le nouveau paramètre through_defaults
est utilisé pour indiquer des valeurs à définir sur la ou les instances de modèle intermédiaire.HttpRequest.headers
a été ajouté pour permettre un accès simplifié aux en-têtes de requêtes.handle_forward_references=True
à serializers.deserialize()
. De plus, loaddata
gère automatiquement les références en aval.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.Client
prend dorénavant en charge automatiquement la sérialisation JSON des listes et tuples data
lorsque content_type='application/json'
.ORACLE_MANAGED_FILES
permet d’utiliser des espaces de tables Oracle Managed Files (OMF).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.ResolverMatch.route
stocke la route du motif d’URL correspondant.MaxValueValidator
, MinValueValidator
, MinLengthValidator
et MaxLengthValidator
acceptent maintenant une valeur limit_value
exécutable.Cette section décrit des modifications qui pourraient être nécessaires dans des moteurs de base de données tiers.
DatabaseFeatures.supports_table_check_constraints
à False
.DatabaseFeatures.supports_ignore_conflicts
à False
.DurationField
ou définir DatabaseFeatures.can_introspect_duration_field
à False
.DatabaseFeatures.uses_savepoints
vaut dorénavant True
par défaut.DatabaseFeatures.supports_partial_indexes
à False
.DatabaseIntrospection.table_name_converter()
et column_name_converter()
ont été supprimées. Les moteurs de base de données de tierce-partie peuvent devoir implémenter DatabaseIntrospection.identifier_converter()
à la place. Dans ce cas, les noms de contraintes renvoyés par DatabaseIntrospection.get_constraints()
doivent être normalisés par identifier_converter()
.Index
vers SchemaEditor
et ces méthodes de SchemaEditor
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()
DatabaseWrapper.__init__()
, allow_thread_sharing
, a été supprimé.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
¶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.
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'))
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')
.
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.
Pour améliorer la lisibilité, le champ de formulaire UUIDField
affiche dorénavant les valeurs avec tirets, par exemple 550e8400-e29b-41d4-a716-446655440000
au lieu de 550e8400e29b41d4a716446655440000
.
Avec SQLite, PositiveIntegerField
et PositiveSmallIntegerField
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 type CHECK 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
et truncatewords_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, et django.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
et false
au lieu de 1
, 2
et 3
. Par rétrocompatibilité, les données avec les anciennes valeurs sont toujours acceptées.
La longueur maximale max_length
de Group.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 que django.utils.http.urlencode()
génèrent maintenant une exception TypeError
si None
est transmis comme valeur à coder, car None
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.
La commande de gestion ping_google
utilise dorénavant https
par défaut au lieu de http
pour l’URL des cartes de sites. Si votre site est en http, utilisez la nouvelle option ping_google --sitemap-uses-http
. Si vous employez la fonction ping_google()
, définissez le nouveau paramètre sitemap_uses_https
à False
.
runserver
no longer supports pyinotify
(replaced by Watchman).
Les fonctions d’agrégat Avg
, StdDev
et Variance
renvoient dorénavant un nombre Decimal
au lieu d’un float
si la valeur d’entrée est un nombre Decimal
.
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 the cache.delete()
or
cache.get()
now raises ValueError
.
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.
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.
django.utils.timezone.FixedOffset
a été rendu obsolète en faveur de datetime.timezone
.QuerySetPaginator
de django.core.paginator.Paginator
a été rendu obsolète.FloatRangeField
dans django.contrib.postgres
a été rendu obsolète en faveur d’un nouveau nom, DecimalRangeField
, pour mieux refléter le type de données numrange
utilisé au niveau de la base de données.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 par ManifestStaticFilesStorage
ou un stockage en nuage de tierce partie.RemoteUserBackend.configure_user()
reçoit dorénavant request
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.SimpleTestCase.allow_database_queries
,
TransactionTestCase.multi_db
, and TestCase.multi_db
attributes are deprecated in favor of SimpleTestCase.databases
,
TransactionTestCase.databases
, and TestCase.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 of allow_database_queries=True
and
multi_db=True
can be achieved by setting databases='__all__'
.déc. 07, 2021