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 de 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.
The Index class creates a b-tree index, as if you
used db_index on the model field or
index_together on the model Meta class. It can be subclassed to support
different index types, such as
GinIndex. It also allows defining the
order (ASC/DESC) for the columns of the 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_hierarchypeut 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.htmlpeut 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
LoginViewetLogoutViewremplacent les vues fonctions obsolèteslogin()etlogout().Les vues classes
PasswordChangeView,PasswordChangeDoneView,PasswordResetView,PasswordResetDoneView,PasswordResetConfirmViewetPasswordResetCompleteViewremplacent 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_logindePasswordResetConfirmViewpermet de connecter automatiquement un utilisateur à la suite d’une réinitialisation de mot de passe fructueuse. Si plusieurs moteursAUTHENTICATION_BACKENDSsont 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_hostsdeLoginViewetLogoutViewpermet d’indiquer un ensemble d’hôtes qui sont fiables pour la redirection après connexion ou déconnexion.Du contenu d’aide
help_texta été ajouté pour les validateurs de mot de passe deUserCreationForm.La requête
HttpRequestest 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.PasswordResetFormprend 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èsmigrateplutô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
dwithina été ajoutée pour SpatiaLite.Les fonctions
AreaetDistanceainsi 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.jsfromhttps://cdnjs.cloudflare.comwhich 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, andoffsetparameters when creatingGDALRasterobjects.La prise en charge SpatiaLite des fonctions
IsValidetMakeValidainsi que de l’expression de rechercheisvalida été ajoutée.La prise en charge Oracle des fonctions
AsGML,BoundingCircleetIsValidainsi que de l’expression de rechercheisvalida été ajoutée.
django.contrib.postgres¶
Le nouveau paramètre
distinctdeStringAggdétermine si les valeurs concaténées seront distinctes.Les nouvelles classes
GinIndexetBrinIndexpermettent de créer des index de typeGINetBRINdans la base de données.django.contrib.postgres.fields.JSONFieldaccepts a newencoderparameter to specify a custom class to encode data types not supported by the standard encoder.The new
CITextmixin andCITextExtensionmigration operation allow using PostgreSQL’scitextextension for case-insensitive lookups. Three fields are provided:CICharField,CIEmailField, andCITextField.La nouvelle fonction
JSONBAggpermer d’agréger des valeurs sous forme de tableau JSON.Le champ de modèle
HStoreFieldet le champ de formulaireHStoreFieldpermettent de stocker des valeurs nulles.
Cache¶
Les moteurs Memcached transmettent dorénavant les contenus de
OPTIONScomme 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_SESSIONSa é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_lockeda é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 dansOPTIONSafin 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_Oracle5.3 a été ajoutée.
Email¶
Le réglage
EMAIL_USE_LOCALTIMEa é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,Filepossède dorénavant les méthodesreadable(),writable()etseekable().
Formulaires¶
The new
empty_valueattribute onCharField,EmailField,RegexField,SlugField, andURLFieldallows 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_GROUPINGprennent en charge le groupement des chiffres non uniformes.
Commandes d’administration¶
La nouvelle option
loaddata --excludepermet d’exclure des modèles et des applications lors du chargement de données par des instantanés.La nouvelle option
diffsettings --defaultpermet de définir un module de réglage autre que celui de Django par défaut pour la comparaison.Les paramètres
app_labellimitent dorénavant la sortie deshowmigrations --plan.
Migrations¶
La prise en charge de la sérialisation d’objets
uuid.UUIDa été ajoutée.
Modèles¶
La prise en charge de valeurs exécutables a été ajoutée dans le paramètre
defaultsdeQuerySet.update_or_create()etget_or_create().ImageFieldnow has a defaultvalidate_image_file_extensionvalidator. (This validator moved to the form field in Django 1.11.2.)Added support for time truncation to
Truncfunctions.Added the
ExtractWeekfunction to extract the week fromDateFieldandDateTimeFieldand exposed it through theweeklookup.Added the
TruncTimefunction to truncateDateTimeFieldto its time component and exposed it through thetimelookup.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=TrueavecFileField.Les paramètres
nulls_firstetnulls_lastont été ajoutés àExpression.asc()etdesc()pour contrôler le tri des valeurs nulles.Les nouvelles méthodes
bitleftshift()andbitrightshift()de l’expressionFpermettent 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.CommonMiddlewaredéfinit dorénavant l’en-têteContent-Lengthpour les réponses qui ne sont pas de type flux.Le réglage
SECURE_HSTS_PRELOADa été ajouté pour permettre d’ajouter la directivepreloadà l’en-têteStrict-Transport-Security.ConditionalGetMiddlewareajoute dorénavant l’en-têteETagaux réponses.
Sérialisation¶
Le nouvel attribut
django.core.serializers.base.Serializer.stream_classpermet 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().DjangoJSONEncoderpeut dorénavant sérialiser les objetstimedelta(utilisé parDurationField).
Gabarits¶
mark_safe()peut dorénavant être utilisé comme décorateur.Le moteur de gabarit
Jinja2accepte dorénavant des processeurs de contexte en définissant l’option'context_processors'dansOPTIONS.La balise
regrouprenvoie dorénavant desnamedtupleau 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
resetcyclea é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.Loaderparticulier.
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-modea é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 --parallelest utilisée.DiscoverRunnerlance 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
FileExtensionValidatoretvalidate_image_file_extensionpermettent 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.gisa é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.mapsis 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é
GEOSGeometrycompare dorénavant aussi avec le SRID.Les composants de formulaires basés sur OpenLayers utilisent dorénavant OpenLayers 3. Les gabarits
gis/openlayers.htmletgis/openlayers-osm.htmlont é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.widgetsetOpenLayersWidgetde 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¶
collectstaticpeut 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 exceptionValueErrorau 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_typeetfield_nameet renvoie le code SQL approprié pour tronquer le champ heurefield_nameà un objet heure restreint à la particule demandée. Le paramètrelookup_typepeut 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_nameettznameet 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_orderingattribute specifies if a database allows defining ordering for columns in indexes. The default value isTrueand 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.inspectdbn’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_casea été renommée enignores_table_name_casepour refléter de manière plus précise son usage.Le paramètre nommé
namea é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 :
SubWidgetRendererMixin,ChoiceFieldRenderer,RadioFieldRenderer,CheckboxFieldRendererChoiceInput,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
pubdateouupdateddate,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.csrfau lieu dedjango.request.La validation
ALLOWED_HOSTSn’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_displayaffiche l’ID de l’objet lié. Enlevez le suffixe_idsi vous souhaitez l’ancien comportement de la représentation textuelle de l’objet.Dans les formulaires de modèles,
CharFieldavecnull=Trueenregistre dorénavant des valeursNULLlors 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
AbstractUseret 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.EmailFieldetURLFieldn’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
checkedetselectedproduits 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é
DateTimeAwareJSONEncoderdeDjangoJSONEncoder(renommé dans Django 1.0) a été supprimé.The
cached template loaderis 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
IntegerFieldutilisetype="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, commeExpiresouCache-Control.UpdateCacheMiddlewareetadd_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.ConditionalGetMiddlewareno longer sets theDateheader as web servers set that header. It also no longer sets theContent-Lengthheader as this is now done byCommonMiddleware.If you have a middleware that modifies a response’s content and appears before
CommonMiddlewarein theMIDDLEWAREorMIDDLEWARE_CLASSESsettings, you must reorder your middleware so that responses aren’t modified afterContent-Lengthis set, or have the response modifying middleware reset theContent-Lengthheader.get_model()etget_models()produisent l’erreurAppRegistryNotReadys’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_settingsa été supprimé.Le décorateur non documenté
django.utils.functional.lazy_propertya été supprimé.Par cohérence avec les requêtes sans parties multiples,
MultiPartParser.parse()définit dorénavantrequest.POSTcomme 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, **kwargstobase_attrs, extra_attrs=None.File-like objects (e.g.,
StringIOandBytesIO) uploaded to anImageFieldusing the test client now require anameattribute with a value that passes thevalidate_image_file_extensionvalidator. See the note inClient.post().FileFieldnow moves rather than copies the file it receives. With the default file upload settings, files larger thanFILE_UPLOAD_MAX_MEMORY_SIZEnow have the same permissions as temporary files (often0o600) rather than the system’s standard umask (often0o6644). Set theFILE_UPLOAD_PERMISSIONSif 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.authont été rendues obsolètes en faveur des nouvelles fonctions classesLoginViewetLogoutView.Le paramètre inutilisé
extra_contextdecontrib.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.authont été rendues obsolètes en faveur des nouvelles vues classesPasswordChangeView,PasswordChangeDoneView,PasswordResetView,PasswordResetDoneView,PasswordResetConfirmViewetPasswordResetCompleteView.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 comportementpylibmccomme attribut de premier niveau dansOPTIONSest obsolète. Définissez plutôt ces réglages sous une clébehaviorsdansOPTIONS.Le paramètre
hostdedjango.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 pasrequestcomme premier paramètre de position sera supprimée dans Django 2.1.Le réglage
USE_ETAGSa été rendu obsolète en faveur deConditionalGetMiddlewarequi ajoute désormais l’en-têteETagaux réponses sans tenir compte du réglage.CommonMiddlewareetdjango.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_fielda é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
renderera é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.