Notes de publication de Django 1.11¶
4 avril 2017
Bienvenue dans Django 1.11 !
Ces notes de publications couvrent les nouvelles fonctionnalités, ainsi que certaines modifications non rétro-compatibles dont il faut être au courant lors la mise à jour depuis Django 1.10 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 1.11 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.8, will end in April 2018.
Compatibilité Python¶
Django 1.11 requires Python 2.7, 3.4, 3.5, 3.6, or 3.7 (as of 1.11.17). We highly recommend and only officially support the latest release of each series.
The Django 1.11.x series is the last to support Python 2. The next major release, Django 2.0, will only support Python 3.4+.
Les avertissements d’obsolescence ne sont plus visibles par défaut¶
Au contraire des versions précédentes de Django, les avertissements d’obsolescence émis par Django ne sont plus affichés par défaut. C’est cohérent avec le comportement par défaut de Python.
Ce changement permet aux applications tierces de prendre en charge à la fois les versions Django 1.11 LTS et Django 1.8 LTS sans devoir ajouter du code pour éviter les avertissements d’obsolescence.
Après la publication de Django 2.0, nous suggérons aux applications tierces de ne plus prendre en charge les versions de Django plus anciennes que 1.11. À 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 2.0.
Quoi de neuf dans Django 1.11¶
Index de modèles basés sur les classes¶
Le nouveau module django.db.models.indexes
contient des classes qui facilitent la création d’index de base de données. Ces index peuvent être ajoutés aux modèles en utilisant l’option Meta.indexes
.
La classe Index
crée un index b-tree comme si vous indiquiez le paramètre db_index
sur le champ de modèle ou index_together
dans la classe Meta
du modèle. Elle peut être héritée pour prendre en charge différents types d’index, tels que GinIndex
. Elle permet aussi de définir le tri (ASC/DESC) pour les colonnes de l’index.
Rendu des composants HTML basé sur des gabarits¶
Pour faciliter la personnalisation des composants de formulaire HTML, leur rendu est dorénavant effectué au travers du système de gabarits plutôt que dans le code Python. Voir L’API du rendu des formulaires.
Il est possible que vous ayez à adapter des composants personnalisés que vous avez écrits en raison de quelques changements non rétrocompatibles.
Expressions Subquery
¶
Les nouvelles expressions de base de données Subquery
et Exists
permettent la création de sous-requêtes explicites. Les sous-requêtes peuvent se référer à des champs de la requête parente avec la classe OuterRef
.
Fonctionnalités mineures¶
django.contrib.admin
¶
ModelAdmin.date_hierarchy
peut dorénavant référencer des champs par-delà des relations.- Le nouveau point d’entrée
ModelAdmin.get_exclude()
permet d’indiquer des champs à exclure en fonction de la requête ou de l’instance de modèle. - Le gabarit
popup_response.html
peut dorénavant être surchargé par application, par modèle ou en définissant l’attributModelAdmin.popup_response_template
.
django.contrib.auth
¶
- Le nombre d’itération par défaut du hacheur de mot de passe PBKDF2 a été augmenté de 20%.
- Les vues classes
LoginView
etLogoutView
remplacent les vues fonctions obsolèteslogin()
etlogout()
. - Les vues classes
PasswordChangeView
,PasswordChangeDoneView
,PasswordResetView
,PasswordResetDoneView
,PasswordResetConfirmView
etPasswordResetCompleteView
remplacent les vues fonctions obsolètespassword_change()
,password_change_done()
,password_reset()
,password_reset_done()
,password_reset_confirm()
etpassword_reset_complete()
. - Le nouvel attribut
post_reset_login
dePasswordResetConfirmView
permet de connecter automatiquement un utilisateur à la suite d’une réinitialisation de mot de passe fructueuse. Si plusieurs moteursAUTHENTICATION_BACKENDS
sont configurés, indiquez lequel sera utilisé en définissant l’attributpost_reset_login_backend
. - Pour éviter l’éventualité d’une divulgation du jeton de réinitialisation du mot de passe par l’en-tête HTTP Referer (par exemple si la page de réinitialisation inclut des références à des fichiers CSS ou JavaScript hébergés sur d’autres domaines), la vue
PasswordResetConfirmView
(mais pas la vue fonction obsolètepassword_reset_confirm()
) stocke le jeton dans une session et redirige sur elle-même pour présenter le formulaire de changement de mot de passe à l’utilisateur sans devoir inclure le jeton dans l’URL. update_session_auth_hash()
effectue dorénavant une rotation de clé de session pour permettre à un changement de mot de passe d’invalider des cookies de session volés.- Le nouvel attribut
success_url_allowed_hosts
deLoginView
etLogoutView
permet d’indiquer un ensemble d’hôtes qui sont fiables pour la redirection après connexion ou déconnexion. - Du contenu d’aide
help_text
a été ajouté pour les validateurs de mot de passe deUserCreationForm
. - La requête
HttpRequest
est dorénavant transmise àauthenticate()
qui à son tour la transmet au moteur d’authentification si celui-ci accepte un paramètrerequest
. - Le signal
user_login_failed()
reçoit dorénavant un paramètrerequest
. PasswordResetForm
prend en charge des modèles d’utilisateur personnalisés qui utilisent un champ d’adresse de courriel nommé autrement que'email'
. DéfinissezCustomUser.EMAIL_FIELD
à la valeur du nom de champ concerné.get_user_model()
peut maintenant être appelé au moment de l’importation, même dans les modules qui définissent des modèles.
django.contrib.contenttypes
¶
- Lorsque des types de contenu périmés sont détectés dans la commande
remove_stale_contenttypes
, vous verrez maintenant apparaître une liste des objets liés qui seront aussi supprimés, tels queauth.Permission
. Précédemment, seuls les types de contenu étaient énumérés (et cette invite apparaissait aprèsmigrate
plutôt que dans une commande séparée).
django.contrib.gis
¶
- Les nouvelles méthodes
GEOSGeometry.from_gml()
etOGRGeometry.from_gml()
permettent de créer des objets géométriques à partir du format GML. - La prise en charge de l’expression de recherche
dwithin
a été ajoutée pour SpatiaLite. - Les fonctions
Area
etDistance
ainsi que les requêtes de distance fonctionnent dorénavant aussi sur SpatiaLite avec des coordonnées géodésiques. - The OpenLayers-based form widgets now use
OpenLayers.js
fromhttps://cdnjs.cloudflare.com
which is more suitable for production use than the oldhttps://openlayers.org/
source. They are also updated to use OpenLayers 3. - Les migrations PostGIS peuvent dorénavant modifier les dimensions de champs.
- Added the ability to pass the
size
,shape
, andoffset
parameters when creatingGDALRaster
objects. - La prise en charge SpatiaLite des fonctions
IsValid
etMakeValid
ainsi que de l’expression de rechercheisvalid
a été ajoutée. - La prise en charge Oracle des fonctions
AsGML
,BoundingCircle
etIsValid
ainsi que de l’expression de rechercheisvalid
a été ajoutée.
django.contrib.postgres
¶
- Le nouveau paramètre
distinct
deStringAgg
détermine si les valeurs concaténées seront distinctes. - Les nouvelles classes
GinIndex
etBrinIndex
permettent de créer des index de typeGIN
etBRIN
dans la base de données. django.contrib.postgres.fields.JSONField
accepts a newencoder
parameter to specify a custom class to encode data types not supported by the standard encoder.- The new
CIText
mixin andCITextExtension
migration operation allow using PostgreSQL’scitext
extension for case-insensitive lookups. Three fields are provided:CICharField
,CIEmailField
, andCITextField
. - La nouvelle fonction
JSONBAgg
permer d’agréger des valeurs sous forme de tableau JSON. - Le champ de modèle
HStoreField
et le champ de formulaireHStoreField
permettent de stocker des valeurs nulles.
Cache¶
- Les moteurs Memcached transmettent dorénavant les contenus de
OPTIONS
comme paramètres nommés aux constructeurs clients, permettant un contrôle plus fin du comportement du client. Voir la documentation des paramètres de cache pour des exemples. - Les moteurs memcached autorisent dorénavant la définition de plusieurs serveurs sous forme de chaîne séparée par des virgules dans
LOCATION
, par commodité avec des service tiers qui utilisent de telles chaînes dans des variables d’environnement.
CSRF¶
- Le réglage
CSRF_USE_SESSIONS
a été ajouté pour permettre de stocker le jeton CSRF dans la session des utilisateurs plutôt que dans un cookie.
Moteurs de base de données¶
- Le paramètre
skip_locked
a été ajouté àQuerySet.select_for_update()
avec PostgreSQL 9.5+ et Oracle pour exécuter des requêtes avecFOR UPDATE SKIP LOCKED
. - Le réglage
TEST['TEMPLATE']
a été ajouté pour permettre aux utilisateurs PostgreSQL d’indiquer un modèle à partir duquel la base de données de test est créée. QuerySet.iterator()
now uses server-side cursors on PostgreSQL. This feature transfers some of the worker memory load (used to hold query results) to the database and might increase database memory usage.- L’option
'isolation_level'
est maintenant prise en charge pour MySQL dansOPTIONS
afin de pourvoir définir le niveau d’isolation des transactions. Pour éviter de possibles pertes de données, il est recommandé de dévier du niveau par défaut de MySQL, « repeatable read » et de passer à « read committed ». - La prise en charge de
cx_Oracle
5.3 a été ajoutée.
Email¶
- Le réglage
EMAIL_USE_LOCALTIME
a été ajouté pour permettre d’envoyer les en-têtes SMTP de date dans le fuseau horaire local plutôt qu’en temps UTC. EmailMessage.attach()
andattach_file()
now fall back to MIME type application/octet-stream when binary content that can’t be decoded as UTF-8 is specified for a text/* attachment.
Stockage de fichier¶
- Pour le rendre encapsulable dans
io.TextIOWrapper
,File
possède dorénavant les méthodesreadable()
,writable()
etseekable()
.
Formulaires¶
- The new
empty_value
attribute onCharField
,EmailField
,RegexField
,SlugField
, andURLField
allows specifying the Python value to use to represent « empty ». - La nouvelle méthode
Form.get_initial_for_field()
renvoie la donnée initiale d’un champ de formulaire.
Internationalisation¶
- La mise en forme des nombres et le réglage
NUMBER_GROUPING
prennent en charge le groupement des chiffres non uniformes.
Commandes d’administration¶
- La nouvelle option
loaddata --exclude
permet d’exclure des modèles et des applications lors du chargement de données par des instantanés. - La nouvelle option
diffsettings --default
permet de définir un module de réglage autre que celui de Django par défaut pour la comparaison. - Les paramètres
app_label
limitent dorénavant la sortie deshowmigrations --plan
.
Migrations¶
- La prise en charge de la sérialisation d’objets
uuid.UUID
a été ajoutée.
Modèles¶
- La prise en charge de valeurs exécutables a été ajoutée dans le paramètre
defaults
deQuerySet.update_or_create()
etget_or_create()
. ImageField
now has a defaultvalidate_image_file_extension
validator. (This validator moved to the form field in Django 1.11.2.)- Added support for time truncation to
Trunc
functions. - Added the
ExtractWeek
function to extract the week fromDateField
andDateTimeField
and exposed it through theweek
lookup. - Added the
TruncTime
function to truncateDateTimeField
to its time component and exposed it through thetime
lookup. - Les expressions sont maintenant possibles dans
QuerySet.values()
etvalues_list()
. - La prise en charge d’expressions de requête dans les recherches qui acceptent plusieurs paramètres, telle que
range
, a été ajoutée. - Il est dorénavant possible d’utiliser l’option
unique=True
avecFileField
. - Les paramètres
nulls_first
etnulls_last
ont été ajoutés àExpression.asc()
etdesc()
pour contrôler le tri des valeurs nulles. - Les nouvelles méthodes
bitleftshift()
andbitrightshift()
de l’expressionF
permettent des opérations de décalage de bit. - Les méthodes
QuerySet.union()
,intersection()
etdifference()
ont été ajoutées.
Requêtes et réponses¶
QueryDict.fromkeys()
a été ajoutée.CommonMiddleware
définit dorénavant l’en-têteContent-Length
pour les réponses qui ne sont pas de type flux.- Le réglage
SECURE_HSTS_PRELOAD
a été ajouté pour permettre d’ajouter la directivepreload
à l’en-têteStrict-Transport-Security
. ConditionalGetMiddleware
ajoute dorénavant l’en-têteETag
aux réponses.
Sérialisation¶
- Le nouvel attribut
django.core.serializers.base.Serializer.stream_class
permet aux sous-classes de personnaliser le flux par défaut. - Le codeur utilisé par le sérialiseur JSON peut dorénavant être personnalisé en passant un paramètre nommé
cls
à la fonctionserializers.serialize()
. DjangoJSONEncoder
peut dorénavant sérialiser les objetstimedelta
(utilisé parDurationField
).
Gabarits¶
mark_safe()
peut dorénavant être utilisé comme décorateur.- Le moteur de gabarit
Jinja2
accepte dorénavant des processeurs de contexte en définissant l’option'context_processors'
dansOPTIONS
. - La balise
regroup
renvoie dorénavant desnamedtuple
au lieu de dictionnaires, ce qui permet de développer directement l’objet groupe dans une boucle, par ex.{% for grouper, list in regrouped %}
. - Une balise de gabarit
resetcycle
a été ajoutée pour permettre de réinitialiser la séquence de la balise de gabaritcycle
. - Il est maintenant possible de définir des répertoires spécifiques à un
filesystem.Loader
particulier.
Tests¶
DiscoverRunner.get_test_runner_kwargs()
a été ajoutée pour permettre de personnaliser les paramètres nommés passés au lanceur de tests.- L’option
test --debug-mode
a été ajoutée pour aider à dépanner les échecs de tests en définissant le réglageDEBUG
àTrue
. - Les nouvelles fonctions
django.test.utils.setup_databases()
(déplacée dedjango.test.runner
) etteardown_databases()
facilitent la construction de ses propres lanceurs de tests. - La prise en charge des sous-tests
unittest.TestCase.subTest()
a été ajoutée lorsque l’optiontest --parallel
est utilisée. DiscoverRunner
lance maintenant les contrôles système au début du lancement de tests. Surchargez la méthodeDiscoverRunner.run_checks()
si vous souhaitez désactiver ce comportement.
Validateurs¶
- Les nouveaux validateurs
FileExtensionValidator
etvalidate_image_file_extension
permettent respectivement de valider des extensions de fichier et des fichiers images.
Changements incompatibles avec les anciennes versions dans Django 1.11¶
django.contrib.gis
¶
- Pour simplifier la base de code et parce qu’il est maintenant plus facile de l’installer qu’au moment où
contrib.gis
a été introduit, GDAL est dorénavant une dépendance obligatoire de GeoDjango. Dans les versions précédentes, elle n’était requise qu’avec SQLite. contrib.gis.maps
is removed as it interfaces with a retired version of the Google Maps API and seems to be unmaintained. If you’re using it, let us know.- L’opérateur d’égalité
GEOSGeometry
compare dorénavant aussi avec le SRID. - Les composants de formulaires basés sur OpenLayers utilisent dorénavant OpenLayers 3. Les gabarits
gis/openlayers.html
etgis/openlayers-osm.html
ont été mis à jour. Vérifiez votre code si vous héritez de ces composants ou que vous étendez leur gabarit. De plus, les nouveaux composants fonctionnent un peu différemment des anciens. Au lieu de présenter une barre d’outils dans l’affichage, il faut cliquer pour commencer de dessiner, cliquer-glisser pour déplacer la carte et cliquer-glisser un point/arête/angle pour le déplacer. - La prise en charge de SpatiaLite < 4.0 a été abandonnée.
- La prise en charge de GDAL 1.7 et 1.8 a été abandonnée.
- Les composants de formulaires dans
contrib.gis.forms.widgets
etOpenLayersWidget
de l’administration utilisent l”API de rendu de formulaires à la place deloader.render_to_string()
. Si vous utilisez un gabarit de composant personnalisé, vous devez être certain que le moteur de rendu de formulaires puisse le localiser. Par exemple, il est possible d’utiliser le moteurTemplatesSetting
.
django.contrib.staticfiles
¶
collectstatic
peut maintenant échouer durant le post-traitement avec un stockage de fichiers statiques hachés si une référence croisée existe (par ex.'foo.css'
référence'bar.css'
qui lui-même référence'foo.css'
) ou si la chaîne de fichiers référençant d’autres fichiers est trop profonde pour être résolue en quelques passes. Dans ce dernier cas, augmentez le nombre de passes en définissantManifestStaticFilesStorage.max_post_process_passes
.- En utilisant
ManifestStaticFilesStorage
, les fichiers statiques non trouvés dans le manifeste au moment de l’exécution produisent dorénavant une exceptionValueError
au lieu de renvoyer un chemin inchangé. Vous pouvez revenir à l’ancien comportement en définissantManifestStaticFilesStorage.manifest_strict
àFalse
.
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 méthode
DatabaseOperations.time_trunc_sql()
a été ajoutée pour gérer la troncature deTimeField
. Elle accepte des paramètreslookup_type
etfield_name
et renvoie le code SQL approprié pour tronquer le champ heurefield_name
à un objet heure restreint à la particule demandée. Le paramètrelookup_type
peut valoir'hour'
,'minute'
ou'second'
. - La méthode
DatabaseOperations.datetime_cast_time_sql()
a été ajoutée pour gérer l’expression de recherchetime
. Elle accepte des paramètresfield_name
ettzname
et renvoie le code SQL approprié pour forcer une valeur date/heure en une valeur heure. - Pour activer la prise en charge de
FOR UPDATE SKIP LOCKED
, définissezDatabaseFeatures.has_select_for_update_skip_locked = True
. - The new
DatabaseFeatures.supports_index_column_ordering
attribute specifies if a database allows defining ordering for columns in indexes. The default value isTrue
and theDatabaseIntrospection.get_constraints()
method should include an'orders'
key in each of the returned dictionaries with a list of'ASC'
and/or'DESC'
values corresponding to the ordering of each column in the index. inspectdb
n’appelle plusDatabaseIntrospection.get_indexes()
qui est obsolète. Les moteurs de base de données personnalisés doivent s’assurer que tous les types d’index sont renvoyés parDatabaseIntrospection.get_constraints()
.- La fonctionnalité
ignores_quoted_identifier_case
a été renommée enignores_table_name_case
pour refléter de manière plus précise son usage. - Le paramètre nommé
name
a été ajouté à la méthodeDatabaseWrapper.create_cursor(self, name=None)
pour permettre l’emploi de curseurs côté serveur pour les moteurs qui les implémentent.
Abandon de la prise en charge de PostgreSQL 9.2 et PostGIS 2.0¶
La prise en charge de PostgreSQL 9.2 par le projet amont se termine en septembre 2017. Par conséquent, Django 1.11 a défini la version 9.3 comme la version minimum de PostgreSQL officiellement prise en charge.
La prise en charge de PostGIS 2.0 a également été abandonnée car PostgreSQL 9.2 est la dernière version la prenant en charge.
De plus, la version minimum de psycopg2 prise en charge est passée de 2.4.5 à 2.5.4.
LiveServerTestCase
se lie au port zéro¶
Plutôt que de considérer un intervalle de ports et de les passer en boucle jusqu’à ce qu’un soit libre, LiveServerTestCase
se lie au port zéro et se fie au système d’exploitation pour attribuer un port libre. La variable d’environnement DJANGO_LIVE_TEST_SERVER_ADDRESS
n’est plus utilisée et par conséquent, l’option manage.py test --liveserver
a été supprimée.
If you need to bind LiveServerTestCase
to a specific port, use the port
attribute added in Django 1.11.2.
Protection contre les redirections non sûres dans les vues django.contrib.auth
et i18n
¶
LoginView
, LogoutView
(ainsi que leurs équivalents obsolètes basés sur des fonctions) et set_language()
protègent les utilisateurs de redirections vers des URL « suivantes » non HTTPS lorsque l’application tourne sous HTTPS.
QuerySet.get_or_create()
et update_or_create()
valident leurs paramètres¶
Pour éviter que des coquilles soient silencieusement ignorées, get_or_create()
et update_or_create()
vérifient que leurs paramètres soient des champs de modèle. Cela devrait être rétrocompatible pour autant que cela ne révèle pas une anomalie dans votre projet.
pytz
est une dépendance obligatoire et la prise en charge de settings.TIME_ZONE = None
est supprimée¶
Pour simplifier la gestion des fuseaux horaires par Django, pytz
est dorénavant une dépendance obligatoire. Cette bibliothèque est automatiquement installée en même temps que Django.
Support for settings.TIME_ZONE = None
is removed as the behavior isn’t
commonly used and is questionably useful. If you want to automatically detect
the timezone based on the system timezone, you can use tzlocal:
from tzlocal import get_localzone
TIME_ZONE = get_localzone().zone
This works similar to settings.TIME_ZONE = None
except that it also sets
os.environ['TZ']
. Let us know
if there’s a use case where you find you can’t adapt your code to set a
TIME_ZONE
.
Changements HTML dans les gabarits d’administration¶
<p class="help">
est remplacé par une balise <div>
pour permettre d’inclure des listes dans le texte d’aide.
Les champs en lecture seule sont enveloppés par <div class="readonly">...</div>
au lieu de <p>...</p>
pour permettre d’inclure tout code HTML dans le contenu du champ.
Changements dus à l’introduction du rendu des composants HTML sur la base de gabarits¶
Certaines classes non documentées dans django.forms.widgets
sont supprimées :
SubWidget
RendererMixin
,ChoiceFieldRenderer
,RadioFieldRenderer
,CheckboxFieldRenderer
ChoiceInput
,RadioChoiceInput
,CheckboxChoiceInput
The undocumented Select.render_option()
method is removed.
La méthode Widget.format_output()
est supprimée. Utilisez à la place un gabarit de composant personnalisé.
Certaines valeurs de composants, telles que les options <select>
sont dorénavant régionalisées quand settings.USE_L10N=True
. Vous pouvez revenir à l’ancien comportement avec des gabarits de composants personnalisés utilisant la balise de gabarit localize
afin de désactiver la régionalisation.
django.template.backends.django.Template.render()
interdit les contextes non dictionnaires¶
Par compatibilité avec les configurations ayant plusieurs moteurs de gabarits, django.template.backends.django.Template.render()
(renvoyé par les API de chargement de gabarit de haut niveau comme par loader.get_template()
) doit recevoir un dictionnaire comme contexte plutôt que des classes Context
ou RequestContext
. Si vous transmettiez l’une de ces classes, transmettez plutôt un dictionnaire, ce qui reste compatible avec les anciennes versions de Django.
Modifications des états de modèles dans les opérations de migration¶
Pour améliorer la rapidité d’application des migrations, le rendu des modèles liés est différé jusqu’à l’opération qui doit les utiliser (par ex. RunPython
). Si vous avez une opération personnalisée qui fonctionne avec des classes ou instances de modèles à partir du paramètre from_state
dans database_forwards()
ou database_backwards()
, il faut produire les états de modèles en utilisant la méthode clear_delayed_apps_cache()
comme expliqué dans écrire ses propres opérations de migration.
Server-side cursors on PostgreSQL¶
The change to make QuerySet.iterator()
use server-side cursors on
PostgreSQL prevents running Django with PgBouncer in transaction pooling mode.
To reallow that, use the DISABLE_SERVER_SIDE_CURSORS
setting (added in Django 1.11.1) in
DATABASES
.
See Transactions groupées et curseurs côté serveur for more discussion.
Divers¶
Si aucun élément d’un flux ne possède d’attribut
pubdate
ouupdateddate
,SyndicationFeed.latest_post_date()
renvoie dorénavant la date/heure actuelle en UTC au lieu d’une date/heure naïve sans fuseau horaire.Les échecs CSRF sont journalisés dans le journaliseur
django.security.csrf
au lieu dedjango.request
.La validation
ALLOWED_HOSTS
n’est plus désactivée lors du lancement des tests. Si votre application inclut des tests avec des noms d’hôte personnalisés, vous devez inclure ces noms dansALLOWED_HOSTS
. Voir Tests avec plusieurs noms d’hôtes.L’utilisation d’un identifiant de clé étrangère (par ex.
'field_id'
) dansModelAdmin.list_display
affiche l’ID de l’objet lié. Enlevez le suffixe_id
si vous souhaitez l’ancien comportement de la représentation textuelle de l’objet.Dans les formulaires de modèles,
CharField
avecnull=True
enregistre dorénavant des valeursNULL
lors de saisies vierges au lieu de chaînes vides.Avec Oracle,
Model.validate_unique()
ne vérifie plus l’unicité des chaînes vides dans la mesure où la base de données interprète la valeur commeNULL
.Si vous héritez de
AbstractUser
et que vous surchargezclean()
, assurez-vous d’appelersuper()
.BaseUserManager.normalize_email()
est appelée dans une nouvelle méthodeAbstractUser.clean()
afin que la normalisation soit appliquée dans des situations comme la validation des modèles de formulaires.EmailField
etURLField
n’acceptent plus le paramètre nomméstrip
. Il a été enlevé car il n’a aucun effet dans les anciennes versions de Django dans la mesure où ces champs enlèvent systématiquement les espaces de début et de fin.Les attributs
checked
etselected
produits par les composants de formulaires utilisent dorénavant la syntaxe booléenne de HTML 5 au lieu de la syntaxechecked="checked"
etselected='selected'
de XHTML.RelatedManager.add()
,remove()
,clear()
etset()
effacent dorénavant le cacheprefetch_related()
.Pour éviter la perte possible de réglages enregistrés,
setup_test_environment()
génère dorénavant une exception si elle est appelée une seconde fois avant d’appelerteardown_test_environment()
.L’alias non documenté
DateTimeAwareJSONEncoder
deDjangoJSONEncoder
(renommé dans Django 1.0) a été supprimé.The
cached template loader
is now enabled ifOPTIONS['loaders']
isn’t specified andOPTIONS['debug']
isFalse
(the latter option defaults to the value ofDEBUG
). This could be backwards-incompatible if you have some template tags that aren’t thread safe.L’invitation à supprimer les types de contenus périmés n’intervient plus après le lancement de la commande
migrate
. Utilisez plutôt la nouvelle commanderemove_stale_contenttypes
.Le composant de formulaire d’administration pour
IntegerField
utilisetype="number"
au lieu detype="text"
.Les en-têtes HTTP conditionnels sont dorénavant analysés et comparés en accord avec la spécification des requêtes conditionnelles RFC 7232 plutôt que l’ancienne RFC 2616.
patch_response_headers()
n’ajoute plus d’en-têteLast-Modified
. En accord avec la RFC 7234#section-4.2.2, cet en-tête est inutile lorsque d’autres en-têtes de cache fournissant une date d’expiration explicite sont présents, commeExpires
ouCache-Control
.UpdateCacheMiddleware
etadd_never_cache_headers()
appellentpatch_response_headers()
et sont donc également touchés par ce changement.Dans les gabarits d’administration,
<p class="help">
est remplacé par une balise<div>
pour permettre d’inclure des listes dans le texte d’aide.ConditionalGetMiddleware
no longer sets theDate
header as web servers set that header. It also no longer sets theContent-Length
header as this is now done byCommonMiddleware
.If you have a middleware that modifies a response’s content and appears before
CommonMiddleware
in theMIDDLEWARE
orMIDDLEWARE_CLASSES
settings, you must reorder your middleware so that responses aren’t modified afterContent-Length
is set, or have the response modifying middleware reset theContent-Length
header.get_model()
etget_models()
produisent l’erreurAppRegistryNotReady
s’ils sont appelés avant que les modèles de toutes les applications aient été chargés. Précédemment, ils n’exigeaient que le chargement des modèles de l’application cible, ce qui pouvait renvoyer des modèles dont certaines relations n’étaient pas encore définies. Si vous avez absolument besoin de l’ancien comportement deget_model()
, définissez le paramètrerequire_ready
àFalse
.L’attribut non utilisé
BaseCommand.can_import_settings
a été supprimé.Le décorateur non documenté
django.utils.functional.lazy_property
a été supprimé.Par cohérence avec les requêtes sans parties multiples,
MultiPartParser.parse()
définit dorénavantrequest.POST
comme non modifiable. Si vous devez modifier cette structureQueryDict
, vous devez la copier préalablement, par exemple avecrequest.POST.copy()
.La prise en charge de
cx_Oracle
< 5.2 a été abandonnée.La prise en charge de IPython < 1.0 a été abandonnée dans la commande
shell
.The signature of private API
Widget.build_attrs()
changed fromextra_attrs=None, **kwargs
tobase_attrs, extra_attrs=None
.File-like objects (e.g.,
StringIO
andBytesIO
) uploaded to anImageField
using the test client now require aname
attribute with a value that passes thevalidate_image_file_extension
validator. See the note inClient.post()
.FileField
now moves rather than copies the file it receives. With the default file upload settings, files larger thanFILE_UPLOAD_MAX_MEMORY_SIZE
now have the same permissions as temporary files (often0o600
) rather than the system’s standard umask (often0o6644
). Set theFILE_UPLOAD_PERMISSIONS
if you need the same permission regardless of file size.
Fonctionnalités rendues obsolètes dans Django 1.11¶
Le décorateur models.permalink()
¶
Utilisez django.urls.reverse()
à la place. Par exemple :
from django.db import models
class MyModel(models.Model):
...
@models.permalink
def url(self):
return ("guitarist_detail", [self.slug])
devient :
from django.db import models
from django.urls import reverse
class MyModel(models.Model):
...
def url(self):
return reverse("guitarist_detail", args=[self.slug])
Divers¶
- Les vues fonctions
login()
etlogout()
decontrib.auth
ont été rendues obsolètes en faveur des nouvelles fonctions classesLoginView
etLogoutView
. - Le paramètre inutilisé
extra_context
decontrib.auth.views.logout_then_login()
est obsolète. - Les vues fonctions
password_change()
,password_change_done()
,password_reset()
,password_reset_done()
,password_reset_confirm()
etpassword_reset_complete()
decontrib.auth
ont été rendues obsolètes en faveur des nouvelles vues classesPasswordChangeView
,PasswordChangeDoneView
,PasswordResetView
,PasswordResetDoneView
,PasswordResetConfirmView
etPasswordResetCompleteView
. django.test.runner.setup_databases()
a été déplacé dansdjango.test.utils.setup_databases()
. L’ancien emplacement est obsolète.django.utils.translation.string_concat()
a été rendue obsolète en faveur dedjango.utils.text.format_lazy()
.string_concat(*strings)
peut être remplacé parformat_lazy('{}' * len(strings), *strings)
.- Pour le moteur de cache
PyLibMCCache
, la transmission de réglages de comportementpylibmc
comme attribut de premier niveau dansOPTIONS
est obsolète. Définissez plutôt ces réglages sous une clébehaviors
dansOPTIONS
. - Le paramètre
host
dedjango.utils.http.is_safe_url()
a été rendu obsolète en faveur du nouveau paramètreallowed_hosts
. - Le masquage des exceptions produites lors du rendu de la balise de gabarit
{% include %}
est obsolète car ce comportement prêtait parfois à confusion. Avec Django 2.1, les exceptions seront propagées. DatabaseIntrospection.get_indexes()
a été rendue obsolète en faveur deDatabaseIntrospection.get_constraints()
.authenticate()
transmet dorénavant un paramètrerequest
à la méthodeauthenticate()
des moteurs d’authentification. La prise en charge des méthodes qui n’acceptent pasrequest
comme premier paramètre de position sera supprimée dans Django 2.1.- Le réglage
USE_ETAGS
a été rendu obsolète en faveur deConditionalGetMiddleware
qui ajoute désormais l’en-têteETag
aux réponses sans tenir compte du réglage.CommonMiddleware
etdjango.utils.cache.patch_response_headers()
ne définiront plus d’en-têteETag
à la fin de la période d’obsolescence. Model._meta.has_auto_field
a été rendu obsolète en faveur du contrôleModel._meta.auto_field is not None
.- L’emploi de groupes d’expression régulière avec
iLmsu#
dansurl()
est obsolète. Le seul groupe utile est(?i)
pour les URL non sensibles à la casse ; toutefois, ces URL ne sont pas à encourager car ils créent des entrées multiples pour les moteurs de recherche, par exemple. Une solution alternative pourrait être de créer une fonctionhandler404
à la recherche de caractères majuscules dans l’URL et redirigeant vers l’équivalent en minuscules. - Le paramètre
renderer
a été ajouté à la méthodeWidget.render()
. Les méthodes qui n’acceptent pas ce paramètre fonctionneront encore le temps de la période d’obsolescence.