Notes de publication de Django 1.9¶
1er décembre 2015
Bienvenue dans Django 1.9 !
These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 1.8 or older versions. We’ve dropped some features that have reached the end of their deprecation cycle, and we’ve begun the deprecation process for some features.
Voir le guide Mise à jour de Django à une version plus récente si vous mettez à jour un projet existant.
Compatibilité Python¶
Django 1.9 requiert Python 2.7, 3.4 ou 3.5. Nous recommandons vivement et nous ne prenons officiellement en charge que la dernière publication de chaque série.
La série Django 1.8 est la dernière à prendre en charge Python 3.2 et 3.3.
Quoi de neuf dans Django 1.9¶
Lancement d’actions après le commit d’une transaction¶
Le nouveau point d’entrée on_commit()
permet de lancer des actions après qu’une transaction de base de données a été validée avec succès. C’est utile pour des tâches telles que l’envoi de courriels de notification, la création de tâches à placer dans une file ou pour l’invalidation des caches.
This functionality from the django-transaction-hooks package has been integrated into Django.
Validation des mots de passe¶
Django offre maintenant la validation de mots de passe pour aider à prévenir l’utilisation de mots de passe faibles par les utilisateurs. La validation est intégrée aux formulaires de changement et de réinitialisation des mots de passe et s’intègre facilement dans n’importe quel autre code. La validation est effectuée par un ou plusieurs validateurs, configurés dans le nouveau réglage AUTH_PASSWORD_VALIDATORS
.
Quatre validateurs sont inclus dans Django ; ceux-ci peuvent imposer une longueur minimale, comparer le mot de passe à des attributs de l’utilisateur tels que leur nom, s’assurer que les mots de passe ne soient pas entièrement numériques, ou comparer avec une liste de mots de passe communs. Vous pouvez combiner plusieurs validateurs, et certains validateurs possèdent des options de configuration propres. Par exemple, vous pouvez choisir de fournir une liste personnalisée de mots de passe communs. Chaque validateur fournit un texte d’aide pour expliquer ses exigences à l’utilisateur.
Par défaut, aucune validation n’est effectuée et tous les mots de passe sont acceptés. Si vous ne mettez pas de contenu dans AUTH_PASSWORD_VALIDATORS
, vous ne verrez aucun changement. Dans les nouveaux projets créés avec le gabarit startproject
par défaut, un ensemble simple de validateurs est activé. Pour activer la validation de base dans les formulaires d’authentification de Django dans votre projet, vous pouvez définir, par exemple :
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
Voir Validation des mots de passe pour plus de détails.
Classes mixins de permissions dans les vues fondées sur les classes¶
Django est dorénavant livré avec les classes mixins AccessMixin
, LoginRequiredMixin
, PermissionRequiredMixin
et UserPassesTestMixin
pour fournir la fonctionnalité de django.contrib.auth.decorators
pour les vues fondées sur les classes. Ces classes proviennent ou s’inspirent en tout cas du projet django-braces.
There are a few differences between Django’s and django-braces
'
implementation, though:
- L’attribut
raise_exception
ne peut valoir queTrue
ouFalse
. Les exceptions ou objets exécutables personnalisés ne sont pas pris en charge. - La méthode
handle_no_permission()
n’accepte pas de paramètrerequest
. La requête en cours est disponible dansself.request
. - La fonction personnalisée
test_func()
deUserPassesTestMixin
n’accepte pas de paramètreuser
. La requête en cours est disponible dansself.request.user
. - L’attribut
permission_required
accepte une chaîne (définissant une permission) ou une liste de chaînes (définissant plusieurs permissions) qui doivent être accordées pour autoriser l’accès. - Le nouvel attribut
permission_denied_message
permet de transmettre un message à l’exceptionPermissionDenied
.
Nouveau style pour contrib.admin
¶
L’interface d’administration présente un nouvel aspect moderne et en aplat avec de nouvelles icônes SVG qui s’affichent parfaitement sur des écrans haute densité. Elle garantit toujours une expérience pleinement fonctionnelle avec les navigateurs de niveau A de YUI. Les navigateurs plus anciens peuvent parfois se comporter en mode dégradé acceptable.
Lancement des tests en parallèle¶
The test
command now supports a --parallel
option to run a project’s tests in multiple processes in parallel.
Chaque processus travaille avec sa propre base de données. Vous devez vous assurer que les différents cas de test n’accèdent pas aux mêmes ressources. Par exemple, les cas de test qui touchent au système de fichiers devraient créer un répertoire temporaire pour leur propre usage.
Cette option est activée par défaut pour la propre suite de tests de Django pour autant que :
- le système d’exploitation le prend en charge (tous sauf Windows)
- le moteur de base de données le prend en charge (tous les moteurs intégrés sauf Oracle)
Fonctionnalités mineures¶
django.contrib.admin
¶
- Les vues d’administration possèdent maintenant des attributs
model_admin
ouadmin_site
. - L’URL de la vue de modification du site d’administration a été modifiée (de
/admin/<app>/<modèle>/<pk>/
par défaut à/admin/<app>/<modèle>/<pk>/change/
). Cela ne devrait pas affecter votre application sauf si vous avez codé en dur des URL d’administration. Dans ce cas, remplacez ces liens de préférence par la résolution inverse des URL d’administration. Notez que l’ancienne URL redirige toujours vers la nouvelle par rétrocompatibilité, mais cela pourrait cesser dans une version future. ModelAdmin.get_list_select_related()
a été ajoutée pour permettre de modifier les valeursselect_related()
utilisées dans la requête de la liste pour modification du site d’administration en fonction de la requête.- La variable de contexte
available_apps
, qui contient la liste des applications disponibles pour l’utilisateur actuel, a été ajoutée à la méthodeAdminSite.each_context()
. AdminSite.empty_value_display
etModelAdmin.empty_value_display
ont été ajoutés pour surcharger l’affichage de valeurs vides dans la liste pour modification du site d’administration. Il est aussi possible de personnaliser la valeur pour chaque champ.- Des événements jQuery ont été ajoutés lorsqu’un sous-formulaire est ajouté ou enlevé sur la page contenant le formulaire de modification.
- Le composant de sélection de l’heure inclut une option « 18:00 » par cohérence avec la présence d’options prédéfinies toutes les 6 heures.
- La génération de « slugs » en JavaScript prend dorénavant en charge les caractères roumains.
django.contrib.admindocs
¶
- La section modèles de
admindocs
documente dorénavant aussi les méthodes qui acceptent des paramètres, plutôt que de les ignorer.
django.contrib.auth
¶
- Le nombre d’itérations par défaut du hachage des mots de passe PBKDF2 a été augmenté de 20%. Cette modification rétrocompatible n’affecte pas ceux qui ont créé une sous-classe de
django.contrib.auth.hashers.PBKDF2PasswordHasher
pour modifier la valeur par défaut. - La classe
BCryptSHA256PasswordHasher
met dorénavant les mots de passe à jour lorsque son attributrounds
est modifié. AbstractBaseUser
etBaseUserManager
ont été déplacés vers un nouveau moduledjango.contrib.auth.base_user
afin qu’ils puissent être importés sans devoir incluredjango.contrib.auth
dansINSTALLED_APPS
(ce qui générait une avertissement d’obsolescence dans les anciennes versions et qui n’est plus pris en charge depuis Django 1.9).- Le paramètre
permission
depermission_required()
accepte toutes les variantes d’éléments itérables, pas seulement les listes et les tuples. - La nouvelle classe
PersistentRemoteUserMiddleware
rend possible l’exploitation deREMOTE_USER
dans les configurations où cet en-tête n’est renseigné que sur les pages de connexion et non sur les autres requêtes de la session. - The
django.contrib.auth.views.password_reset()
view accepts anextra_email_context
parameter.
django.contrib.contenttypes
¶
- Il est maintenant possible d’utiliser
order_with_respect_to
avec une relationGenericForeignKey
.
django.contrib.gis
¶
- Toutes les méthodes
GeoQuerySet
ont été rendues obsolètes et remplacées par des fonctions de base de données équivalentes. Dès que les anciennes méthodes auront été remplacées dans votre code, il est alors même possible d’enlever le gestionnaire spécialGeoManager
de vos classes de modèles géographiques. - L’interface GDAL prend désormais en charge l’instanciation d”objets GDALRaster à base de fichiers et en mémoire à partir de données brutes. Les propriétés matricielles telles que la projection ou les valeurs de pixels peuvent maintenant être modifiées.
- Pour les utilisateurs de PostGIS, le nouveau champ
RasterField
permet de stocker des objets GDALRaster. Il prend en charge la création automatique d’index spatial et la reprojection lors de l’enregistrement d’un modèle. Il ne supporte pas encore l’interrogation spatiale. - La nouvelle méthode
GDALRaster.warp()
permet de déformer une structure matricielle en indiquant des propriétés cibles telles que l’origine, la largeur, la hauteur ou la taille de pixel (parmi d’autres). - La nouvelle méthode
GDALRaster.transform()
permet de transformer une structure matricielle dans un autre système de référence spatiale en indiquant un codesrid
cible. - La nouvelle classe
GeoIP2
permet d’exploiter les bases de données GeoLite2 de MaxMind qui incluent la prise en charge des adresses IPv6. - The default OpenLayers library version included in widgets has been updated from 2.13 to 2.13.1.
django.contrib.postgres
¶
- La prise en charge de l’interrogation
rangefield.contained_by
a été ajoutée pour certains champs intégrés qui correspondent aux champs d’intervalle. - Added
django.contrib.postgres.fields.JSONField
. - Des Fonctions d’agrégation spécifiques à PostgreSQL ont été ajoutées.
- La fonction de base de données
TransactionNow
a été ajoutée.
django.contrib.sessions
¶
- Le modèle de session et les classes
SessionStore
pour les moteursdb
etcached_db
ont été refactorisés pour permettre de bâtir sur ceux-ci un moteur de session personnalisé fondé sur une base de données. Voir Extension des moteurs de sessions s’appuyant sur une base de données pour plus de détails.
django.contrib.sites
¶
get_current_site()
gère maintenant le cas oùrequest.get_host()
renvoiedomaine:port
, par exempleexemple.com:80
. Si la recherche échoue parce que l’hôte ne correspond pas à un enregistrement dans la base de données et que l’hôte dispose d’un port, la recherche est relancée sans le port et uniquement avec la partie du domaine.
django.contrib.syndication
¶
- Plusieurs annexes par élément de flux sont maintenant possibles. Si plusieurs annexes sont définies pour un flux RSS, une exception est produite car les flux RSS, au contraire des flux Atom, ne gèrent pas plusieurs annexes par élément de flux.
Cache¶
django.core.cache.backends.base.BaseCache
possède maintenant une méthodeget_or_set()
.django.views.decorators.cache.never_cache()
envoie maintenant des en-têtes plus persuasifs (no-cache, no-store, must-revalidate
ont été ajoutés àCache-Control
) puor mieux empêcher le cache. Ceci a aussi été ajouté à Django 1.8.8.
CSRF¶
- Le nom d’en-tête de requête utilisé pour l’authentification CSRF peut être personnalisé avec
CSRF_HEADER_NAME
. - L’en-tête de référant CSRF est maintenant validée en fonction du réglage
CSRF_COOKIE_DOMAIN
si celui-ci est défini. Voir Fonctionnement pour plus de détails. - Le nouveau réglage
CSRF_TRUSTED_ORIGINS
donne la possibilité d’autoriser des requêtes non sûres (par ex.POST
) d’origine croisée sur HTTPS.
Moteurs de base de données¶
- Le moteur PostgreSQL (
django.db.backends.postgresql_psycopg2
) est également disponible en tant quedjango.db.backends.postgresql
. L’ancien nom continuera d’être disponible par rétro-compatibilité.
Stockage de fichier¶
Storage.get_valid_name()
est dorénavant appelée lorsqueupload_to
est un objet exécutable.File
possède maintenant la méthodeseekable()
avec Python 3.
Formulaires¶
ModelForm
accepte la nouvelle optionMeta
field_classes
pour personnaliser les types de champs. Voir Surcharge des champs par défaut pour plus de détails.- Vous pouvez maintenant définir l’ordre dans lequel les champs de formulaire sont affichés en vous servant de l’attribut
field_order
, du paramètre de constructeurfield_order
ou de la méthodeorder_fields()
. - Un préfixe de formulaire peut être défini dans une classe de formulaire, non seulement lors de l’instanciation du formulaire. Voir Préfixes de formulaires pour plus de détails.
- Vous pouvez maintenant définir des paramètres nommés que vous souhaitez transmettre au constructeur des formulaires dans un jeu de formulaires.
SlugField
accepte dorénavant un paramètreallow_unicode
pour autoriser les caractères Unicode dans les « slugs ».CharField
accepte maintenant un paramètrestrip
pour épurer les données saisies d’éventuelles espaces initiales ou finales. Comme la valeur par défaut estTrue
, le comportement est donc différent des versions précédentes.- Les champs de formulaire acceptent maintenant un paramètre
disabled
ce qui provoque l’affichage d’un composant de champ désactivé dans les navigateurs. - Il est maintenant possible de personnaliser les champs de formulaire liés aux données en surchargeant la méthode
get_bound_field()
.
Vues génériques¶
- Les vues fondées sur les classes générées par
as_view()
possèdent maintenant les attributsview_class
etview_initkwargs
. method_decorator()
peut maintenant être utilisée avec une liste ou un tuple de décorateurs. On peut aussi l’utiliser pour décorer des classes au lieu de méthodes.
Internationalisation¶
- La vue
django.views.i18n.set_language()
redirige maintenant correctement vers les URL traduites lorsqu’elles sont disponibles. - The
django.views.i18n.javascript_catalog()
view now works correctly if used multiple times with different configurations on the same page. - La fonction
django.utils.timezone.make_aware()
possède un nouveau paramètreis_dst
pour aider à résoudre les heures ambiguës lors des passages heure d’été / heure d’hiver. - Les variantes de langue prises en charge par gettext peuvent maintenant être utilisées. Elles sont généralement utilisées pour des langues qui s’écrivent dans différentes écritures, par exemple latin et cyrillique (comme par ex.
be@latin
). - Added the
django.views.i18n.json_catalog()
view to help build a custom client-side i18n library upon Django translations. It returns a JSON object containing a translations catalog, formatting settings, and a plural rule. - L’attribut
name_translated
a été ajouté à l’objet renvoyé par la balise de gabaritget_language_info
. Un filtre de gabarit similaire a aussi été ajouté :language_name_translated
. - Vous pouvez maintenant exécuter
compilemessages
à partir du répertoire racine d’un projet et elle trouvera tous les fichiers de messages qui ont été créés parmakemessages
. makemessages
now callsxgettext
once per locale directory rather than once per translatable file. This speeds up localization builds.blocktrans
permet d’attribuer son résultat à une variable avecasvar
.- Deux nouvelles langues sont disponibles : l’espagnol colombien et le gaélique écossais.
Commandes d’administration¶
- La nouvelle commande
sendtestemail
permet d’envoyer un courriel de test pour confirmer facilement que l’envoi de courriels au travers de Django fonctionne. - Pour améliorer la lisibilité du code SQL généré par la commande
sqlmigrate
, le code SQL généré pour chaque opération de migration est précédé par la description de l’opération. - Le résultat produit par la commande
dumpdata
est maintenant ordonné de manière déterministe. De plus, lorsque l’option--output
est donnée, la commande affiche aussi une barre de progression dans le terminal. - La commande
createcachetable
offre maintenant une option--dry-run
pour afficher le code SQL au lieu de l’exécuter. - La commande
startapp
crée un fichierapps.py
. Comme celui-ci ne contient pasdefault_app_config
(une API découragée), vous devez indiquer le chemin de la configuration d’application dansINSTALLED_APPS
, par exemple'polls.apps.PollsConfig'
, pour que la configuration soit utilisée (au lieu d’un simple'polls'
). - Avec le moteur PostgreSQL, la commande
dbshell
peut se connecter à la base de données en utilisant le mot de passe provenant du fichier des réglages (au lieu de devoir le saisir manuellement). - Le paquet
django
peut être exécuté comme un script, comme par exemplepython -m django
, ce qui produira le même comportement quedjango-admin
. - Les commandes d’administration possédant l’option
--noinput
acceptent maintenant également--no-input
comme alias de cette option.
Migrations¶
Initial migrations are now marked with an
initial = True
class attribute which allowsmigrate --fake-initial
to more easily detect initial migrations.La prise en charge de la sérialisation d’instances
functools.partial
etLazyObject
a été ajoutée.Lorsqu’on indique la valeur
None
pour un élément dansMIGRATION_MODULES
, Django considère que cette application ne possède pas de migration.Lors de l’application des migrations, l’étape « rendu des états de modèles » qui apparaît lors de l’exécution des migrations avec une verbosité de 2 ou plus élevée calcule maintenant uniquement les états des migrations qui ont déjà été appliquées. Les états de modèles des migrations en cours d’application sont générés à la demande, ce qui réduit drastiquement la quantité de mémoire nécessaire.
Cependant, cette amélioration n’est pas disponible lors de l’inversion des migrations et, dans ce cas, il est toujours nécessaire de précalculer et de stocker les états des migrations intermédiaires.
Cette amélioration est aussi la cause de la non prise en charge par Django des plans de migration mixtes. Ces plans mixtes consistent en une liste de migrations où certaines doivent être appliquées et d’autres inversées. Cela n’a jamais été officiellement pris en charge et il n’existait pas d’API publique qui s’appuyait sur ce comportement.
La commande
squashmigrations
accepte dorénavant la possibilité d’indiquer la migration de départ à partir de laquelle les migrations sont fusionnées.
Modèles¶
QuerySet.bulk_create()
fonctionne maintenant aussi pour des modèles mandataires.- La configuration des bases de données contient une nouvelle option
TIME_ZONE
pour interagir avec les bases de données qui stockent les dates/heures en heure locale et qui ne prennent pas en charge les fuseaux horaires lorsqueUSE_TZ
vautTrue
. - La méthode
RelatedManager.set()
a été ajoutée aux gestionnaires de relations créés par les champsForeignKey
,GenericForeignKey
etManyToManyField
. - La méthode
add()
du côté opposé d’une clé étrangère possède maintenant un paramètrebulk
pour permettre l’exécution d’une seule requête quel que soit le nombre d’objets à ajouter, au lieu d’exiger une requête par objet. - Le paramètre
keep_parents
a été ajouté àModel.delete()
pour permettre de ne supprimer que les données « enfant » d’un modèle qui hérite d’autres tables. Model.delete()
etQuerySet.delete()
renvoient le nombre d’objets supprimés.- Un contrôle système a été ajouté pour empêcher de définir à la fois
Meta.ordering
etorder_with_respect_to
pour le même modèle. - Les interrogations de
date et d'heure
peuvent être suivies d’autres interrogations (commeexact
,gt
,lt
, etc.). Par exemple,Entry.objects.filter(pub_date__month__gt=6)
. - Les interrogations d’heure (heure, minute, seconde) sont maintenant prises en charge par
TimeField
pour tous les moteurs de base de données. Sauf pour SQLite, ces interrogations étaient déjà disponibles depuis Django 1.7, mais non documentées. - Le paramètre
output_field
a été ajouté pour permettre l’agrégationAvg
sur des colonnes non numériques, comme par exempleDurationField
. - L’interrogation
date
a été ajoutée àDateTimeField
pour permettre d’interroger le champ par la seule portion de date. - Les fonctions de base de données
Greatest
etLeast
ont été ajoutées. - La fonction de base de données
Now
a été ajoutée ; celle-ci renvoie la date et l’heure courantes. Transform
est dorénavant une sous-classe de Func(), ce qui permet aux objetsTransform
d’être utilisés dans la partie droite d’une expression, comme pour les objetsFunc
normaux. Cela permet d’inscrire certaines fonctions de base de données commeLength
,Lower
etUpper
en tant que transformations.SlugField
accepte dorénavant un paramètreallow_unicode
pour autoriser les caractères Unicode dans les « slugs ».- Il est maintenant possible de référencer les annotations dans
QuerySet.distinct()
. - Avec SQLite,
connection.queries
affiche les requêtes avec les paramètres substitués. - Les expressions de requête peuvent maintenant être utilisées lors de la création de nouvelles instances de modèles avec
save()
,create()
etbulk_create()
.
Requêtes et réponses¶
- Tant que
HttpResponse.reason_phrase
n’est pas explicitement défini, sa valeur est maintenant déterminée par la valeur actuelle deHttpResponse.status_code
. La modification destatus_code
en dehors du constructeur modifie également la valeur dereason_phrase
. - La vue de débogage affiche maintenant les détails de la chaîne des exceptions avec Python 3.
- Les vues d’erreur 40x par défaut acceptent maintenant un second paramètre positionnel, l’exception qui a déclenché l’erreur.
- Les gestionnaires des vues d’erreur prennent maintenant en charge
TemplateResponse
, qui sont couramment utilisées avec les vues fondées sur les classes. - Les exceptions générées par la méthode
render()
sont maintenant aussi transmises à la méthodeprocess_exception()
de chaque intergiciel. - Les intergiciels de requête peuvent maintenant définir
HttpRequest.urlconf
àNone
pour annuler tout changement effectué par un intergiciel précédent et revenir à la valeurROOT_URLCONF
de départ. - Le contrôle
DISALLOWED_USER_AGENTS
dansCommonMiddleware
génère maintenant une exceptionPermissionDenied
au lieu deHttpResponseForbidden
afin que la vuehandler403
soit appelée. HttpRequest.get_port()
a été ajoutée pour récupérer le port d’origine de la requête.- Le paramètre
json_dumps_params
a été ajouté àJsonResponse
pour permettre la transmission de paramètres nommés à l’appeljson.dumps()
utilisé pour produire la réponse. - The
BrokenLinkEmailsMiddleware
now ignores 404s when the referer is equal to the requested URL. To circumvent the empty referer check already implemented, some web bots set the referer to the requested URL.
Gabarits¶
- Les balises de gabarit créés avec l’utilitaire
simple_tag()
peuvent maintenant stocker leur résultat dans une variable de gabarit en utilisant le paramètreas
. - La méthode
Context.setdefault()
a été ajoutée. - Le journaliseur django.template a été ajouté et reçoit les messages suivants :
- Un message de niveau
DEBUG
pour les variables de contexte manquantes. - Un message de niveau
WARNING
pour les exceptions non interceptées générées pendant le rendu d’une balise{% include %}
lorsque le mode débogage est désactivé (utile car{% include %}
réduit au silence l’exception et renvoie une chaîne vide).
- Un message de niveau
- La balise de gabarit
firstof
permet de stocker son résultat dans une variable avecas
. Context.update()
peut maintenant être utilisée comme gestionnaire de contexte.- Les chargeurs de gabarit de Django peuvent maintenant étendre des gabarits de manière récursive.
- Le gabarit « postmortem » de la page de débogage inclut dorénavant un résultat pour chaque moteur de gabarit installé.
- L”intégration de la page de débogage pour les moteurs de gabarit personnalisés a été ajoutée.
- Il est maintenant possible d’inscrire explicitement des bibliothèques et des éléments intégrés pour le moteur
DjangoTemplates
au moyen du réglage de gabaritOPTIONS
. - Les filtres
timesince
ettimeuntil
ont été améliorés pour tenir compte des années bissextiles pour de grands intervalles de temps. - La balise
include
met dorénavant en cache les objets gabarits analysés durant le processus de rendu des gabarits, accélérant la réutilisation dans des endroits comme les bouclesfor
.
Tests¶
- La méthode
json()
a été ajoutée aux réponses du client de test pour donner accès au corps de la réponse en format JSON. - La méthode
force_login()
a été ajoutée au client de test. Utilisez cette méthode pour simuler l’effet d’un utilisateur se connectant au site tout en évitant de passer par les étapes d’authentification et de vérification delogin()
.
URL¶
- Les assertions de type « lookaround » sont maintenant autorisées dans les expressions régulières des motifs d’URL.
- The application namespace can now be set using an
app_name
attribute on the included module or object. It can also be set by passing a 2-tuple of (<list of patterns>, <application namespace>) as the first argument toinclude()
. - Des contrôles système ont été ajoutés pour les erreurs courantes dans les motifs d’URL.
Validateurs¶
django.core.validators.int_list_validator()
a été ajouté pour générer des validateurs de chaînes contenant des nombres entiers séparés par un caractère personnalisé.EmailValidator
limite dorénavant la longueur des parties de noms de domaine à 63 caractères, en accord avec la RFC 1034.validate_unicode_slug()
a été ajouté pour valider des « slugs » pouvant contenir des caractères Unicode.
Changements incompatibles avec les anciennes versions dans Django 1.9¶
Avertissement
En plus des modifications détaillées dans cette section, prenez soin de parcourir les Features removed in 1.9 énumérant les fonctionnalités ayant terminé leur cycle d’obsolescence et qui ont donc été supprimées. Si vous n’avez pas mis à jour votre code dans le temps imparti par la période d’obsolescence d’une certaine fonctionnalité, sa suppression pourrait apparaître comme un changement incompatible avec les anciennes versions.
API de moteur de base de données¶
Quelques nouveaux tests reposent sur la capacité du moteur d’examiner les valeurs par défaut des colonnes (renvoyant le résultat dans
Field.default
). Vous pouvez définir la fonctionnalité de base de donnéescan_introspect_default
àFalse
si votre moteur ne permet pas cette introspection. Vous pouvez passer en revue la mise en œuvre sur les moteurs inclus dans Django pour référence (#24245).Il est déconseillé d’enregistrer un adaptateur ou un convertisseur global au niveau du module DB-API pour gérer les informations de fuseau horaire des valeurs
datetime
passées comme paramètres de requête ou renvoyés comme résultats de requêtes avec des bases de données qui ne prennent pas en charge les fuseaux horaires. Cela peut engendrer des conflits avec d’autres bibliothèques.La méthode recommandée pour ajouter un fuseau horaire aux valeurs
datetime
obtenues de la base de données est d’inscrire un convertisseur pour les champsDateTimeField
dansDatabaseOperations.get_db_converters()
.La fonctionnalité de base de données
needs_datetime_string_cast
a été supprimée. Les moteurs de base de données qui la définissent doivent inscrire un convertisseur à la place, comme expliqué ci-dessus.Les méthodes
DatabaseOperations.value_to_db_<type>()
ont été renommées enadapt_<type>field_value()
par cohérence avec les méthodesconvert_<type>field_value()
.Pour utiliser la nouvelle interrogation
date
, les moteurs de base de données tiers pourraient devoir implémenter la méthodeDatabaseOperations.datetime_cast_date_sql()
.La méthode
DatabaseOperations.time_extract_sql()
a été ajoutée. Elle appelle la méthode existantedate_extract_sql()
. Cette méthode est surchargée par le moteur SQLite pour ajouter les interrogations horaires (heure, minute, seconde) aux champsTimeField
. Certains moteurs de base de données tiers pourraient avoir à faire de même.La méthode
DatabaseOperations.datetime_cast_sql()
(à ne pas confondre avecDatabaseOperations.datetime_cast_date_sql()
citée ci-dessus) a été supprimée. Cette méthode étaient utilisée pour mettre en forme les dates avec Oracle bien avant la version 1.0, mais n’a pas été surchargée par d’autres moteurs intégrés durant des années, et n’a pas non plus été appelée depuis d’autres endroits du code ou des tests de Django.Afin de prendre en charge la parallélisation des tests, il faut implémenter la méthode
DatabaseCreation._clone_test_db()
et définirDatabaseFeatures.can_clone_databases = True
. Il peut être nécessaire d’ajusterDatabaseCreation.get_test_db_clone_settings()
.
Les réglages par défaut qui étaient des tuples sont maintenant des listes¶
Les réglages par défaut dans django.conf.global_settings
comportaient aussi bien des listes que des tuples. Tous les réglages qui étaient précédemment des tuples sont maintenant des listes.
L’attribut is_usable
des chargeurs de gabarit a été supprimé¶
Django template loaders previously required an is_usable
attribute to be
defined. If a loader was configured in the template settings and this attribute
was False
, the loader would be silently ignored. In practice, this was only
used by the egg loader to detect if setuptools
was installed. The
is_usable
attribute is now removed and the egg loader instead fails at
runtime if setuptools
is not installed.
Les chargeurs de gabarits basés sur le système de fichiers interceptent plus précisément les exceptions¶
Lors de l’utilisation des chargeurs de gabarits filesystem.Loader
ou app_directories.Loader
, les version précédentes de Django généraient une erreur TemplateDoesNotExist
si une source de gabarit existait mais qu’elle n’était pas lisible. Cela pouvait se produire dans diverses circonstances, comme par exemple si Django n’avait pas les permissions d’ouvrir le fichier ou que la source du gabarit était un répertoire. Dorénavant, Django ne masque une exception que si la source du gabarit n’existe pas. Dans tous les autres cas, ce sera l’exception IOError
d’origine qui sera générée.
Les redirections HTTP ne doivent plus forcément être des URI absolues¶
Les redirections relatives ne sont plus converties en URI absolues. La RFC 2616 exige que l’en-tête Location
des réponses de redirection soit une URI absolue, mais cette norme a été remplacée par la RFC 7231 qui autorise les URI relatives dans Location
, reconnaissant ainsi la pratique réelle des agents utilisateurs, dont presque tous acceptent cette façon de faire.
Consequently, the expected URLs passed to assertRedirects
should generally
no longer include the scheme and domain part of the URLs. For example,
self.assertRedirects(response, 'http://testserver/some-url/')
should be
replaced by self.assertRedirects(response, '/some-url/')
(unless the
redirection specifically contained an absolute URL).
In the rare case that you need the old behavior (discovered with an ancient
version of Apache with mod_scgi
that interprets a relative redirect as an
« internal redirect »), you can restore it by writing a custom middleware:
class LocationHeaderFix(object):
def process_response(self, request, response):
if "Location" in response:
response["Location"] = request.build_absolute_uri(response["Location"])
return response
Abandon de la prise en charge de PostgreSQL 9.0¶
La prise en charge de PostgreSQL 9.0 par le projet amont s’est terminée en septembre 2015. Par conséquent, Django 1.9 a défini la version 1.9 comme la version minimum de PostgreSQL officiellement prise en charge.
Abandon de la prise en charge de Oracle 11.1¶
La prise en charge de Oracle 11.1 par le projet amont s’est terminée en août 2015. Par conséquent, Django 1.9 a défini la version 11.2 comme la version minimum de Oracle officiellement prise en charge.
Suppression de LoaderOrigin
et StringOrigin
des gabarits¶
Dans les versions précédentes de Django, quand un moteur de gabarit était initialisé avec debug=True
, une instance de django.template.loader.LoaderOrigin
ou de django.template.base.StringOrigin
était définie comme attribut d’origine sur l’objet gabarit. Ces classes ont été réunies dans Origin
et l’attribut est maintenant toujours défini, indépendamment du réglage de débogage du moteur. Pour un niveau minimal de rétrocompatibilité, les anciens noms de classes seront conservés comme alias de la nouvelle classe Origin
jusqu’à Django 2.0.
Changements de la configuration de journalisation par défaut¶
To make it easier to write custom logging configurations, Django’s default
logging configuration no longer defines django.request
and
django.security
loggers. Instead, it defines a single django
logger,
filtered at the INFO
level, with two handlers:
console
: filtered at theINFO
level and only active ifDEBUG=True
.mail_admins
: filtered at theERROR
level and only active ifDEBUG=False
.
Si vous ne surchargez pas la journalisation par défaut de Django, vous ne devriez constater que des changements minimes dans le comportement, mais vous pourriez voir certains nouveaux messages dans la console runserver
, par exemple.
Si vous surchargez la journalisation par défaut de Django, vous devriez vérifier la manière dont votre configuration fusionne avec les nouveaux paramètres par défaut.
Détails HttpRequest
dans les rapports d’erreur¶
Il était redondant d’afficher les détails complets de la requête HttpRequest
chaque fois qu’elle apparaissait comme variable de la pile d’appels dans la version HTML de la page de débogage et du courriel d’erreur. Ainsi, la requête HTTP est affichée dorénavant avec la même représentation standard que les autres variables (repr(request)
). En conséquence, la méthode ExceptionReporterFilter.get_request_repr()
et la fonction non documentée django.http.build_request_repr()
ont été supprimées.
Les contenus de la version textuelle du courriel ont été modifiés pour fournir une trace d’appels de la même structure que dans le cas de requêtes AJAX. Les détails de la trace d’appels sont produits par la méthode ExceptionReporter.get_traceback_text()
.
Suppression des adaptateurs et convertisseurs globaux de fuseau horaire pour les objets date/heure¶
Django n’inscrit plus d’adaptateurs ou de convertisseurs globaux pour la gestion des informations de fuseau horaire pour les valeurs datetime
envoyées à la base de données en tant que paramètres de requête ou lues à partir de la base de données pour des résultats de requête. Ce changement affecte les projets qui répondent à toutes les conditions suivantes :
- Le réglage
USE_TZ
contientTrue
. - La base de données est SQLite, MySQL, Oracle ou une autre base de données tierce qui ne prend pas en charge les fuseaux horaires. En cas de doute, vous pouvez vérifier la valeur de
connection.features.supports_timezones
. - Le code interroge la base de données en dehors de l’ORM, typiquement avec
cursor.execute(sql, params)
.
Si vous passez des paramètres datetime
avec fuseau horaire à de telles requêtes, vous devriez les transformer en dates/heures naïves en UTC :
from django.utils import timezone
param = timezone.make_naive(param, timezone.utc)
Si vous ne le faites pas, la conversion sera effectuée comme dans les versions précédentes (avec un avertissement d’obsolescence) jusqu’à Django 1.11. Django 2.0 n’effectuera plus de conversion, ce qui pourrait aboutir à des corruptions de données.
Si vous lisez des valeurs datetime
dans les résultats, elles seront naïves au lieu d’être conscientes. Vous pouvez compenser comme ceci :
from django.utils import timezone
value = timezone.make_aware(value, timezone.utc)
Tout ceci n’est pas nécessaire si vous interrogez la base de données au travers de l’ORM, même si vous utilisez des requêtes raw()
. L’ORM se charge de gérer les informations de fuseau horaire.
Les modules de balises de gabarit sont importés au moment où les gabarits sont configurés¶
Le moteur DjangoTemplates
procède dorénavant à la découverte de modules de balises de gabarit installés lors de son instanciation. Ce changement permet d’activer explicitement des bibliothèques par la clé 'libraries'
de OPTIONS
dans la définition d’un moteur DjangoTemplates
. D’éventuelles erreurs d’importation ou de syntaxe dans les modules de balises de gabarit aboutissent à un échec rapide au moment de l’instanciation, plutôt qu’au moment de la première compilation d’un gabarit avec une balise {% load %}
.
Suppression de django.template.base.add_to_builtins()
¶
Même s’il s’agissait d’une API privée, les projets utilisaient souvent add_to_builtins()
pour rendre disponibles les balises et filtres de gabarit sans devoir utiliser la balise {% load %}
. Cette API a été formalisée. Les projets doivent dorénavant intégrer les bibliothèques au moyen de la clé 'builtins'
de OPTIONS
lors de la définition d’un moteur DjangoTemplates
.
Le résultat de simple_tag
passe maintenant toujours par conditional_escape
¶
In general, template tags do not autoescape their contents, and this behavior is
documented. For tags like
inclusion_tag
, this is not a problem because
the included template will perform autoescaping. For assignment_tag()
,
the output will be escaped when it is used as a variable in the template.
Cependant, pour les cas d’utilisation prévus pour simple_tag
, il est très facile de se retrouver avec du code HTML incorrect et par conséquent avec un risque de faille XSS. Par exemple :
@register.simple_tag(takes_context=True)
def greeting(context):
return "Hello {0}!".format(context["request"].user.first_name)
Dans les versions précédentes de Django, ceci est considéré comme une faille XSS car user.first_name
n’est pas échappé.
Dans Django 1.9, c’est corrigé : si le contexte du gabarit possède autoescape=True
(par défaut), simple_tag
fera passer le résultat de la fonction de la balise par conditional_escape()
.
Pour corriger vos balises simple_tag
, voici les bonnes pratiques à appliquer :
- Tout code produisant du HTML devrait soit utiliser le système des gabarits, soit
format_html()
. - Si le résultat d’une balise
simple_tag
a besoin d’être échappé, utilisezescape()
ouconditional_escape()
. - Si vous êtes absolument certain que vous produisez du code HTML provenant d’une source fiable (par ex. un champ de CMS qui stocke du HTML saisi par des administrateurs), vous pouvez le signaler comme tel en utilisant
mark_safe()
.
Les balises qui suivent ces règles seront correctes et sûres, qu’elles fonctionnent avec Django 1.9+ ou des versions plus anciennes.
Paginator.page_range
¶
Paginator.page_range
est dorénavant un itérateur au lieu d’une liste.
Dans les versions de Django avant 1.8, Paginator.page_range
renvoyait un objet list
en Python 2 et un objet range
en Python 3. Django 1.8 renvoie toujours une liste, mais un itérateur est plus efficace.
Le code existant qui dépend des fonctionnalités spécifiques des objets list
, comme l’indiçage, peut se charger de transformer l’itérateur en list
avec la fonction list()
.
Interrogation implicite __in
des QuerySet
supprimée¶
Dans les versions précédentes, des requêtes telles que :
Model.objects.filter(related_id=RelatedModel.objects.all())
étaient implicitement converties en :
Model.objects.filter(related_id__in=RelatedModel.objects.all())
ce qui produisait du code SQL du style "related_id IN (SELECT id FROM ...)"
.
L’opération __in
implicite n’est plus effectuée, ce qui fait que le « IN » SQL est maintenant « = », et si la sous-requête renvoie plusieurs résultats, la plupart des bases de données vont générer une erreur.
Navigateurs pris en charge par contrib.admin
¶
Le site d’administration ne prend plus en charge les versions d’Internet Explorer 8 et plus anciennes, dans la mesure où ces navigateurs ont atteint leur fin de vie officielle.
Les images et le style CSS qui prenait en charge Internet Explorer 6 et 7 ont été supprimés. Les icônes PNG et GIF ont été remplacées par des icônes SVG qui ne sont pas prises en charge par Internet Explorer 8 ou les versions plus anciennes.
The jQuery library embedded in the admin has been upgraded from version 1.11.2 to 2.1.4. jQuery 2.x has the same API as jQuery 1.x, but does not support Internet Explorer 6, 7, or 8, allowing for better performance and a smaller file size. If you need to support IE8 and must also use the latest version of Django, you can override the admin’s copy of jQuery with your own by creating a Django application with this structure:
app/static/admin/js/vendor/
jquery.js
jquery.min.js
SyntaxError
when installing Django setuptools
5.5.x¶
When installing Django 1.9 or 1.9.1 with setuptools
5.5.x, you’ll see:
Compiling django/conf/app_template/apps.py ...
File "django/conf/app_template/apps.py", line 4
class {{ camel_case_app_name }}Config(AppConfig):
^
SyntaxError: invalid syntax
Compiling django/conf/app_template/models.py ...
File "django/conf/app_template/models.py", line 1
{{ unicode_literals }}from django.db import models
^
SyntaxError: invalid syntax
It’s safe to ignore these errors (Django will still install just fine), but you
can avoid them by upgrading setuptools
to a more recent version. If you’re
using pip, you can upgrade pip using python -m pip install -U pip
which
will also upgrade setuptools
. This is resolved in later versions of Django
as described in the Notes de publication de Django 1.9.2.
Divers¶
- The jQuery static files in
contrib.admin
have been moved into avendor/jquery
subdirectory. - The text displayed for null columns in the admin changelist
list_display
cells has changed from(None)
(or its translated equivalent) to-
(a dash). django.http.responses.REASON_PHRASES
anddjango.core.handlers.wsgi.STATUS_CODE_TEXT
have been removed. Use Python’s Standard Library instead:http.client.responses
for Python 3 and httplib.responses for Python 2.ValuesQuerySet
andValuesListQuerySet
have been removed.- The
admin/base.html
template no longer setswindow.__admin_media_prefix__
orwindow.__admin_utc_offset__
. Image references in JavaScript that used that value to construct absolute URLs have been moved to CSS for easier customization. The UTC offset is stored on a data attribute of the<body>
tag. CommaSeparatedIntegerField
validation has been refined to forbid values like','
,',1'
, and'1,,2'
.- Form initialization was moved from the
ProcessFormView.get()
method to the newFormMixin.get_context_data()
method. This may be backwards incompatible if you have overridden theget_context_data()
method without callingsuper()
. - La prise en charge de PostGIS 1.5 a été abandonnée.
- Le champ
django.contrib.sites.models.Site.domain
a été défini commeunique
. - In order to enforce test isolation, database queries are not allowed
by default in
SimpleTestCase
tests anymore. You can disable this behavior by setting theallow_database_queries
class attribute toTrue
on your test class. ResolverMatch.app_name
was changed to contain the full namespace path in the case of nested namespaces. For consistency withResolverMatch.namespace
, the empty value is now an empty string instead ofNone
.- For security hardening, session keys must be at least 8 characters.
- Private function
django.utils.functional.total_ordering()
has been removed. It contained a workaround for afunctools.total_ordering()
bug in Python versions older than 2.7.3. - XML serialization (either through
dumpdata
or the syndication framework) used to output any characters it received. Now if the content to be serialized contains any control characters not allowed in the XML 1.0 standard, the serialization will fail with aValueError
. CharField
now strips input of leading and trailing whitespace by default. This can be disabled by setting the newstrip
argument toFalse
.- Template text that is translated and uses two or more consecutive percent
signs, e.g.
"%%"
, may have a newmsgid
aftermakemessages
is run (most likely the translation will be marked fuzzy). The newmsgid
will be marked"#, python-format"
. - If neither
request.current_app
norContext.current_app
are set, theurl
template tag will now use the namespace of the current request. Setrequest.current_app
toNone
if you don’t want to use a namespace hint. - The
SILENCED_SYSTEM_CHECKS
setting now silences messages of all levels. Previously, messages ofERROR
level or higher were printed to the console. - The
FlatPage.enable_comments
field is removed from theFlatPageAdmin
as it’s unused by the application. If your project or a third-party app makes use of it, create a custom ModelAdmin to add it back. - The return value of
setup_databases()
and the first argument ofteardown_databases()
changed. They used to be(old_names, mirrors)
tuples. Now they’re just the first item,old_names
. - By default
LiveServerTestCase
attempts to find an available port in the 8081-8179 range instead of just trying port 8081. - Les contrôles système pour
ModelAdmin
vérifient maintenant les instances plutôt que les classes. - The private API to apply mixed migration plans has been dropped for performance reasons. Mixed plans consist of a list of migrations where some are being applied and others are being unapplied.
- The related model object descriptor classes in
django.db.models.fields.related
(private API) are moved from therelated
module torelated_descriptors
and renamed as follows:ReverseSingleRelatedObjectDescriptor
isForwardManyToOneDescriptor
SingleRelatedObjectDescriptor
isReverseOneToOneDescriptor
ForeignRelatedObjectsDescriptor
isReverseManyToOneDescriptor
ManyRelatedObjectsDescriptor
isManyToManyDescriptor
- If you implement a custom
handler404
view, it must return a response with an HTTP 404 status code. UseHttpResponseNotFound
or passstatus=404
to theHttpResponse
. Otherwise,APPEND_SLASH
won’t work correctly withDEBUG=False
.
Fonctionnalités rendues obsolètes dans Django 1.9¶
assignment_tag()
¶
Django 1.4 added the assignment_tag
helper to ease the creation of
template tags that store results in a template variable. The
simple_tag()
helper has gained this same
ability, making the assignment_tag
obsolete. Tags that use
assignment_tag
should be updated to use simple_tag
.
{% cycle %}
syntax with comma-separated arguments¶
The cycle
tag supports an inferior old syntax from previous Django
versions:
{% cycle row1,row2,row3 %}
Its parsing caused bugs with the current syntax, so support for the old syntax will be removed in Django 1.10 following an accelerated deprecation.
ForeignKey
and OneToOneField
on_delete
argument¶
In order to increase awareness about cascading model deletion, the
on_delete
argument of ForeignKey
and OneToOneField
will be required
in Django 2.0.
Update models and existing migrations to explicitly set the argument. Since the
default is models.CASCADE
, add on_delete=models.CASCADE
to all
ForeignKey
and OneToOneField
s that don’t use a different option. You
can also pass it as the second positional argument if you don’t care about
compatibility with older versions of Django.
Field.rel
changes¶
Field.rel
and its methods and attributes have changed to match the related
fields API. The Field.rel
attribute is renamed to remote_field
and many
of its methods and attributes are either changed or renamed.
The aim of these changes is to provide a documented API for relation fields.
GeoManager
and GeoQuerySet
custom methods¶
All custom GeoQuerySet
methods (area()
, distance()
, gml()
, …)
have been replaced by equivalent geographic expressions in annotations (see in
new features). Hence the need to set a custom GeoManager
to GIS-enabled
models is now obsolete. As soon as your code doesn’t call any of the deprecated
methods, you can simply remove the objects = GeoManager()
lines from your
models.
Template loader APIs have changed¶
Django template loaders have been updated to allow recursive template
extending. This change necessitated a new template loader API. The old
load_template()
and load_template_sources()
methods are now deprecated.
Details about the new API can be found in the template loader
documentation.
Passing a 3-tuple or an app_name
to include()
¶
The instance namespace part of passing a tuple as an argument to include()
has been replaced by passing the namespace
argument to include()
. For
example:
polls_patterns = [
url(...),
]
urlpatterns = [
url(r"^polls/", include((polls_patterns, "polls", "author-polls"))),
]
devient :
polls_patterns = (
[
url(...),
],
"polls",
) # 'polls' is the app_name
urlpatterns = [
url(r"^polls/", include(polls_patterns, namespace="author-polls")),
]
The app_name
argument to include()
has been replaced by passing a
2-tuple (as above), or passing an object or module with an app_name
attribute (as below). If the app_name
is set in this new way, the
namespace
argument is no longer required. It will default to the value of
app_name
. For example, the URL patterns in the tutorial are changed from:
urlpatterns = [url(r"^polls/", include("polls.urls", namespace="polls")), ...]
to:
urlpatterns = [
url(r"^polls/", include("polls.urls")), # 'namespace="polls"' removed
...,
]
app_name = "polls" # added
urlpatterns = [...]
This change also means that the old way of including an AdminSite
instance
is deprecated. Instead, pass admin.site.urls
directly to
django.conf.urls.url()
:
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r"^admin/", admin.site.urls),
]
URL application namespace required if setting an instance namespace¶
In the past, an instance namespace without an application namespace would serve the same purpose as the application namespace, but it was impossible to reverse the patterns if there was an application namespace with the same name. Includes that specify an instance namespace require that the included URLconf sets an application namespace.
current_app
parameter to contrib.auth
views¶
All views in django.contrib.auth.views
have the following structure:
def view(request, ..., current_app=None, ...):
...
if current_app is not None:
request.current_app = current_app
return TemplateResponse(request, template_name, context)
As of Django 1.8, current_app
is set on the request
object. For
consistency, these views will require the caller to set current_app
on the
request
instead of passing it in a separate argument.
django.contrib.gis.geoip
¶
The django.contrib.gis.geoip2
module supersedes
django.contrib.gis.geoip
. The new module provides a similar API except that
it doesn’t provide the legacy GeoIP-Python API compatibility methods.
Divers¶
- The
weak
argument todjango.dispatch.signals.Signal.disconnect()
has been deprecated as it has no effect. - The
check_aggregate_support()
method ofdjango.db.backends.base.BaseDatabaseOperations
has been deprecated and will be removed in Django 2.0. The more generalcheck_expression_support()
should be used instead. django.forms.extras
is deprecated. You can findSelectDateWidget
indjango.forms.widgets
(or simplydjango.forms
) instead.- Private API
django.db.models.fields.add_lazy_relation()
is deprecated. - The
django.contrib.auth.tests.utils.skipIfCustomUser()
decorator is deprecated. With the test discovery changes in Django 1.6, the tests fordjango.contrib
apps are no longer run as part of the user’s project. Therefore, the@skipIfCustomUser
decorator is no longer needed to decorate tests indjango.contrib.auth
. - If you customized some error handlers, the view
signatures with only one request parameter are deprecated. The views should
now also accept a second
exception
positional parameter. - The
django.utils.feedgenerator.Atom1Feed.mime_type
anddjango.utils.feedgenerator.RssFeed.mime_type
attributes are deprecated in favor ofcontent_type
. Signer
now issues a warning if an invalid separator is used. This will become an exception in Django 1.10.django.db.models.Field._get_val_from_obj()
is deprecated in favor ofField.value_from_object()
.django.template.loaders.eggs.Loader
is deprecated as distributing applications as eggs is not recommended.- The
callable_obj
keyword argument toSimpleTestCase.assertRaisesMessage()
is deprecated. Pass the callable as a positional argument instead. - The
allow_tags
attribute on methods ofModelAdmin
has been deprecated. Useformat_html()
,format_html_join()
, ormark_safe()
when constructing the method’s return value instead. - The
enclosure
keyword argument toSyndicationFeed.add_item()
is deprecated. Use the newenclosures
argument which accepts a list ofEnclosure
objects instead of a single one. - The
django.template.loader.LoaderOrigin
anddjango.template.base.StringOrigin
aliases fordjango.template.base.Origin
are deprecated.
Features removed in 1.9¶
These features have reached the end of their deprecation cycle and are removed in Django 1.9. See Fonctionnalités déconseillées dans 1.7 for details, including how to remove usage of these features.
django.utils.dictconfig
is removed.django.utils.importlib
is removed.django.utils.tzinfo
is removed.django.utils.unittest
is removed.- The
syncdb
command is removed. django.db.models.signals.pre_syncdb
anddjango.db.models.signals.post_syncdb
is removed.- Support for
allow_syncdb
on database routers is removed. - Automatic syncing of apps without migrations is removed. Migrations are
compulsory for all apps unless you pass the
migrate --run-syncdb
option. - The SQL management commands for apps without migrations,
sql
,sqlall
,sqlclear
,sqldropindexes
, andsqlindexes
, are removed. - Support for automatic loading of
initial_data
fixtures and initial SQL data is removed. - All models need to be defined inside an installed application or declare an
explicit
app_label
. Furthermore, it isn’t possible to import them before their application is loaded. In particular, it isn’t possible to import models inside the root package of an application. - The model and form
IPAddressField
is removed. A stub field remains for compatibility with historical migrations. AppCommand.handle_app()
is no longer supported.RequestSite
andget_current_site()
are no longer importable fromdjango.contrib.sites.models
.- FastCGI support via the
runfcgi
management command is removed. django.utils.datastructures.SortedDict
is removed.ModelAdmin.declared_fieldsets
is removed.- The
util
modules that provided backwards compatibility are removed:django.contrib.admin.util
django.contrib.gis.db.backends.util
django.db.backends.util
django.forms.util
ModelAdmin.get_formsets
is removed.- The backward compatible shims introduced to rename the
BaseMemcachedCache._get_memcache_timeout()
method toget_backend_timeout()
is removed. - The
--natural
and-n
options fordumpdata
are removed. - The
use_natural_keys
argument forserializers.serialize()
is removed. - Private API
django.forms.forms.get_declared_fields()
is removed. - The ability to use a
SplitDateTimeWidget
withDateTimeField
is removed. - The
WSGIRequest.REQUEST
property is removed. - The class
django.utils.datastructures.MergeDict
is removed. - The
zh-cn
andzh-tw
language codes are removed. - The internal
django.utils.functional.memoize()
is removed. django.core.cache.get_cache
is removed.django.db.models.loading
a été supprimé.- Passing callable arguments to querysets is no longer possible.
BaseCommand.requires_model_validation
is removed in favor ofrequires_system_checks
. Admin validators is replaced by admin checks.- The
ModelAdmin.validator_class
anddefault_validator_class
attributes are removed. ModelAdmin.validate()
is removed.django.db.backends.DatabaseValidation.validate_field
is removed in favor of thecheck_field
method.- The
validate
management command is removed. django.utils.module_loading.import_by_path
is removed in favor ofdjango.utils.module_loading.import_string
.ssi
andurl
template tags are removed from thefuture
template tag library.django.utils.text.javascript_quote()
is removed.- Database test settings as independent entries in the database settings,
prefixed by
TEST_
, are no longer supported. - The
cache_choices
option toModelChoiceField
andModelMultipleChoiceField
is removed. - The default value of the
RedirectView.permanent
attribute has changed fromTrue
toFalse
. django.contrib.sitemaps.FlatPageSitemap
is removed in favor ofdjango.contrib.flatpages.sitemaps.FlatPageSitemap
.- L’API privée
django.test.utils.TestTemplateLoader
a été supprimée. - Le module
django.contrib.contenttypes.generic
a été supprimé.