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

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 et LogoutView remplacent les vues fonctions obsolètes login() et logout().
  • Les vues classes PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView et PasswordResetCompleteView remplacent les vues fonctions obsolètes password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm() et password_reset_complete().
  • Le nouvel attribut post_reset_login de PasswordResetConfirmView permet de connecter automatiquement un utilisateur à la suite d’une réinitialisation de mot de passe fructueuse. Si plusieurs moteurs AUTHENTICATION_BACKENDS sont configurés, indiquez lequel sera utilisé en définissant l’attribut post_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ète password_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 de LoginView et LogoutView 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 de UserCreationForm.
  • La requête HttpRequest est dorénavant transmise à authenticate() qui à son tour la transmet au moteur d’authentification si celui-ci accepte un paramètre request.
  • Le signal user_login_failed() reçoit dorénavant un paramètre request.
  • PasswordResetForm prend en charge des modèles d’utilisateur personnalisés qui utilisent un champ d’adresse de courriel nommé autrement que 'email'. Définissez CustomUser.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 que auth.Permission. Précédemment, seuls les types de contenu étaient énumérés (et cette invite apparaissait après migrate plutôt que dans une commande séparée).

django.contrib.gis

  • Les nouvelles méthodes GEOSGeometry.from_gml() et OGRGeometry.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 et Distance 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 from https://cdnjs.cloudflare.com which is more suitable for production use than the old https://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, and offset parameters when creating GDALRaster objects.
  • La prise en charge SpatiaLite des fonctions IsValid et MakeValid ainsi que de l’expression de recherche isvalid a été ajoutée.
  • La prise en charge Oracle des fonctions AsGML, BoundingCircle et IsValid ainsi que de l’expression de recherche isvalid a été ajoutée.

django.contrib.postgres

  • Le nouveau paramètre distinct de StringAgg détermine si les valeurs concaténées seront distinctes.
  • Les nouvelles classes GinIndex et BrinIndex permettent de créer des index de type GIN et BRIN dans la base de données.
  • django.contrib.postgres.fields.JSONField accepts a new encoder parameter to specify a custom class to encode data types not supported by the standard encoder.
  • The new CIText mixin and CITextExtension migration operation allow using PostgreSQL’s citext extension for case-insensitive lookups. Three fields are provided: CICharField, CIEmailField, and CITextField.
  • 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 formulaire HStoreField 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 avec FOR 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 dans OPTIONS 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() and attach_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éthodes readable(), writable() et seekable().

Formulaires

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 de showmigrations --plan.

Migrations

  • La prise en charge de la sérialisation d’objets uuid.UUID a été ajoutée.

Modèles

Requêtes et 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 fonction serializers.serialize().
  • DjangoJSONEncoder peut dorénavant sérialiser les objets timedelta (utilisé par DurationField).

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' dans OPTIONS.
  • La balise regroup renvoie dorénavant des namedtuple 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 gabarit cycle.
  • Il est maintenant possible de définir des répertoires spécifiques à un filesystem.Loader particulier.

Tests

Validateurs

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 et gis/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 et OpenLayersWidget de l’administration utilisent l”API de rendu de formulaires à la place de loader.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 moteur TemplatesSetting.

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éfinissant ManifestStaticFilesStorage.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 exception ValueError au lieu de renvoyer un chemin inchangé. Vous pouvez revenir à l’ancien comportement en définissant ManifestStaticFilesStorage.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 de TimeField. Elle accepte des paramètres lookup_type et field_name et renvoie le code SQL approprié pour tronquer le champ heure field_name à un objet heure restreint à la particule demandée. Le paramètre lookup_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 recherche time. Elle accepte des paramètres field_name et tzname 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éfinissez DatabaseFeatures.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 is True and the DatabaseIntrospection.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 plus DatabaseIntrospection.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 par DatabaseIntrospection.get_constraints().
  • La fonctionnalité ignores_quoted_identifier_case a été renommée en ignores_table_name_case pour refléter de manière plus précise son usage.
  • Le paramètre nommé name a été ajouté à la méthode DatabaseWrapper.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 ou updateddate, 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 de django.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 dans ALLOWED_HOSTS. Voir Tests avec plusieurs noms d’hôtes.

  • L’utilisation d’un identifiant de clé étrangère (par ex. 'field_id') dans ModelAdmin.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 avec null=True enregistre dorénavant des valeurs NULL 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 comme NULL.

  • Si vous héritez de AbstractUser et que vous surchargez clean(), assurez-vous d’appeler super(). BaseUserManager.normalize_email() est appelée dans une nouvelle méthode AbstractUser.clean() afin que la normalisation soit appliquée dans des situations comme la validation des modèles de formulaires.

  • EmailField et URLField 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 et selected produits par les composants de formulaires utilisent dorénavant la syntaxe booléenne de HTML 5 au lieu de la syntaxe checked="checked" et selected='selected' de XHTML.

  • RelatedManager.add(), remove(), clear() et set() effacent dorénavant le cache prefetch_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’appeler teardown_test_environment().

  • L’alias non documenté DateTimeAwareJSONEncoder de DjangoJSONEncoder (renommé dans Django 1.0) a été supprimé.

  • The cached template loader is now enabled if OPTIONS['loaders'] isn’t specified and OPTIONS['debug'] is False (the latter option defaults to the value of DEBUG). 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 commande remove_stale_contenttypes.

  • Le composant de formulaire d’administration pour IntegerField utilise type="number" au lieu de type="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ête Last-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, comme Expires ou Cache-Control. UpdateCacheMiddleware et add_never_cache_headers() appellent patch_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 the Date header as web servers set that header. It also no longer sets the Content-Length header as this is now done by CommonMiddleware.

    If you have a middleware that modifies a response’s content and appears before CommonMiddleware in the MIDDLEWARE or MIDDLEWARE_CLASSES settings, you must reorder your middleware so that responses aren’t modified after Content-Length is set, or have the response modifying middleware reset the Content-Length header.

  • get_model() et get_models() produisent l’erreur AppRegistryNotReady 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 de get_model(), définissez le paramètre require_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énavant request.POST comme non modifiable. Si vous devez modifier cette structure QueryDict, vous devez la copier préalablement, par exemple avec request.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 from extra_attrs=None, **kwargs to base_attrs, extra_attrs=None.

  • File-like objects (e.g., StringIO and BytesIO) uploaded to an ImageField using the test client now require a name attribute with a value that passes the validate_image_file_extension validator. See the note in Client.post().

  • FileField now moves rather than copies the file it receives. With the default file upload settings, files larger than FILE_UPLOAD_MAX_MEMORY_SIZE now have the same permissions as temporary files (often 0o600) rather than the system’s standard umask (often 0o6644). Set the FILE_UPLOAD_PERMISSIONS if you need the same permission regardless of file size.

Fonctionnalités rendues obsolètes dans Django 1.11

Divers

  • Les vues fonctions login() et logout() de contrib.auth ont été rendues obsolètes en faveur des nouvelles fonctions classes LoginView et LogoutView.
  • Le paramètre inutilisé extra_context de contrib.auth.views.logout_then_login() est obsolète.
  • Les vues fonctions password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm() et password_reset_complete() de contrib.auth ont été rendues obsolètes en faveur des nouvelles vues classes PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView et PasswordResetCompleteView.
  • django.test.runner.setup_databases() a été déplacé dans django.test.utils.setup_databases(). L’ancien emplacement est obsolète.
  • django.utils.translation.string_concat() a été rendue obsolète en faveur de django.utils.text.format_lazy(). string_concat(*strings) peut être remplacé par format_lazy('{}' * len(strings), *strings).
  • Pour le moteur de cache PyLibMCCache, la transmission de réglages de comportement pylibmc comme attribut de premier niveau dans OPTIONS est obsolète. Définissez plutôt ces réglages sous une clé behaviors dans OPTIONS.
  • Le paramètre host de django.utils.http.is_safe_url() a été rendu obsolète en faveur du nouveau paramètre allowed_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 de DatabaseIntrospection.get_constraints().
  • authenticate() transmet dorénavant un paramètre request à la méthode authenticate() des moteurs d’authentification. La prise en charge des méthodes qui n’acceptent pas request 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 de ConditionalGetMiddleware qui ajoute désormais l’en-tête ETag aux réponses sans tenir compte du réglage. CommonMiddleware et django.utils.cache.patch_response_headers() ne définiront plus d’en-tête ETag à la fin de la période d’obsolescence.
  • Model._meta.has_auto_field a été rendu obsolète en faveur du contrôle Model._meta.auto_field is not None.
  • L’emploi de groupes d’expression régulière avec iLmsu# dans url() 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 fonction handler404 à 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éthode Widget.render(). Les méthodes qui n’acceptent pas ce paramètre fonctionneront encore le temps de la période d’obsolescence.
Back to Top