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.
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.
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.
Cette fonctionnalité provenant du paquet django-transaction-hooks a été intégrée dans Django.
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.
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:
raise_exception
ne peut valoir que True
ou False
. Les exceptions ou objets exécutables personnalisés ne sont pas pris en charge.handle_no_permission()
n’accepte pas de paramètre request
. La requête en cours est disponible dans self.request
.test_func()
de UserPassesTestMixin
n’accepte pas de paramètre user
. La requête en cours est disponible dans self.request.user
.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.permission_denied_message
permet de transmettre un message à l’exception PermissionDenied
.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.
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 :
django.contrib.admin
¶model_admin
ou admin_site
./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 valeurs select_related()
utilisées dans la requête de la liste pour modification du site d’administration en fonction de la requête.available_apps
, qui contient la liste des applications disponibles pour l’utilisateur actuel, a été ajoutée à la méthode AdminSite.each_context()
.AdminSite.empty_value_display
et ModelAdmin.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.django.contrib.admindocs
¶admindocs
documente dorénavant aussi les méthodes qui acceptent des paramètres, plutôt que de les ignorer.django.contrib.auth
¶django.contrib.auth.hashers.PBKDF2PasswordHasher
pour modifier la valeur par défaut.BCryptSHA256PasswordHasher
met dorénavant les mots de passe à jour lorsque son attribut rounds
est modifié.AbstractBaseUser
et BaseUserManager
ont été déplacés vers un nouveau module django.contrib.auth.base_user
afin qu’ils puissent être importés sans devoir inclure django.contrib.auth
dans INSTALLED_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).permission
de permission_required()
accepte toutes les variantes d’éléments itérables, pas seulement les listes et les tuples.PersistentRemoteUserMiddleware
rend possible l’exploitation de REMOTE_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.django.contrib.auth.views.password_reset()
view accepts an
extra_email_context
parameter.django.contrib.contenttypes
¶order_with_respect_to
avec une relation GenericForeignKey
.django.contrib.gis
¶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écial GeoManager
de vos classes de modèles géographiques.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.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).GDALRaster.transform()
permet de transformer une structure matricielle dans un autre système de référence spatiale en indiquant un code srid
cible.GeoIP2
permet d’exploiter les bases de données GeoLite2 de MaxMind qui incluent la prise en charge des adresses IPv6.django.contrib.postgres
¶rangefield.contained_by
a été ajoutée pour certains champs intégrés qui correspondent aux champs d’intervalle.JSONField
a été ajouté.TransactionNow
a été ajoutée.django.contrib.sessions
¶SessionStore
pour les moteurs db
et cached_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()
renvoie domaine:port
, par exemple exemple.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
¶django.core.cache.backends.base.BaseCache
possède maintenant une méthode get_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_HEADER_NAME
.CSRF_COOKIE_DOMAIN
si celui-ci est défini. Voir Fonctionnement pour plus de détails.CSRF_TRUSTED_ORIGINS
donne la possibilité d’autoriser des requêtes non sûres (par ex. POST
) d’origine croisée sur HTTPS.django.db.backends.postgresql_psycopg2
) est également disponible en tant que django.db.backends.postgresql
. L’ancien nom continuera d’être disponible par rétro-compatibilité.Storage.get_valid_name()
est dorénavant appelée lorsque upload_to
est un objet exécutable.File
possède maintenant la méthode seekable()
avec Python 3.ModelForm
accepte la nouvelle option Meta
field_classes
pour personnaliser les types de champs. Voir Surcharge des champs par défaut pour plus de détails.field_order
, du paramètre de constructeur field_order
ou de la méthode order_fields()
.SlugField
accepte dorénavant un paramètre allow_unicode
pour autoriser les caractères Unicode dans les « slugs ».CharField
accepte maintenant un paramètre strip
pour épurer les données saisies d’éventuelles espaces initiales ou finales. Comme la valeur par défaut est True
, le comportement est donc différent des versions précédentes.disabled
ce qui provoque l’affichage d’un composant de champ désactivé dans les navigateurs.get_bound_field()
.as_view()
possèdent maintenant les attributs view_class
et view_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.django.views.i18n.set_language()
redirige maintenant correctement vers les URL traduites lorsqu’elles sont disponibles.django.views.i18n.javascript_catalog()
view now works correctly
if used multiple times with different configurations on the same page.django.utils.timezone.make_aware()
possède un nouveau paramètre is_dst
pour aider à résoudre les heures ambiguës lors des passages heure d’été / heure d’hiver.be@latin
).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.name_translated
a été ajouté à l’objet renvoyé par la balise de gabarit get_language_info
. Un filtre de gabarit similaire a aussi été ajouté : language_name_translated
.compilemessages
à partir du répertoire racine d’un projet et elle trouvera tous les fichiers de messages qui ont été créés par makemessages
.makemessages
appelle maintenant xgettext une fois par répertoire de langue au lieu d’une fois par fichier traduisible. Cela accélère la construction des catalogues de traduction.blocktrans
permet d’attribuer son résultat à une variable avec asvar
.sendtestemail
permet d’envoyer un courriel de test pour confirmer facilement que l’envoi de courriels au travers de Django fonctionne.sqlmigrate
, le code SQL généré pour chaque opération de migration est précédé par la description de l’opération.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.createcachetable
offre maintenant une option --dry-run
pour afficher le code SQL au lieu de l’exécuter.startapp
crée un fichier apps.py
. Comme celui-ci ne contient pas default_app_config
(une API découragée), vous devez indiquer le chemin de la configuration d’application dans INSTALLED_APPS
, par exemple 'polls.apps.PollsConfig'
, pour que la configuration soit utilisée (au lieu d’un simple 'polls'
).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).django
peut être exécuté comme un script, comme par exemple python -m django
, ce qui produira le même comportement que django-admin
.--noinput
acceptent maintenant également --no-input
comme alias de cette option.Initial migrations are now marked with an initial = True
class attribute which allows
migrate --fake-initial
to more easily detect initial migrations.
La prise en charge de la sérialisation d’instances functools.partial
et LazyObject
a été ajoutée.
Lorsqu’on indique la valeur None
pour un élément dans MIGRATION_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.
QuerySet.bulk_create()
fonctionne maintenant aussi pour des modèles mandataires.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 lorsque USE_TZ
vaut True
.RelatedManager.set()
a été ajoutée aux gestionnaires de relations créés par les champs ForeignKey
, GenericForeignKey
et ManyToManyField
.add()
du côté opposé d’une clé étrangère possède maintenant un paramètre bulk
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.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()
et QuerySet.delete()
renvoient le nombre d’objets supprimés.Meta.ordering
et order_with_respect_to
pour le même modèle.date et d'heure
peuvent être suivies d’autres interrogations (comme exact
, gt
, lt
, etc.). Par exemple, Entry.objects.filter(pub_date__month__gt=6)
.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.output_field
a été ajouté pour permettre l’agrégation Avg
sur des colonnes non numériques, comme par exemple DurationField
.date
a été ajoutée à DateTimeField
pour permettre d’interroger le champ par la seule portion de date.Greatest
et Least
ont été ajouté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 objets Transform
d’être utilisés dans la partie droite d’une expression, comme pour les objets Func
normaux. Cela permet d’inscrire certaines fonctions de base de données comme Length
, Lower
et Upper
en tant que transformations.SlugField
accepte dorénavant un paramètre allow_unicode
pour autoriser les caractères Unicode dans les « slugs ».QuerySet.distinct()
.connection.queries
affiche les requêtes avec les paramètres substitués.save()
, create()
et bulk_create()
.HttpResponse.reason_phrase
n’est pas explicitement défini, sa valeur est maintenant déterminée par la valeur actuelle de HttpResponse.status_code
. La modification de status_code
en dehors du constructeur modifie également la valeur de reason_phrase
.TemplateResponse
, qui sont couramment utilisées avec les vues fondées sur les classes.render()
sont maintenant aussi transmises à la méthode process_exception()
de chaque intergiciel.HttpRequest.urlconf
à None
pour annuler tout changement effectué par un intergiciel précédent et revenir à la valeur ROOT_URLCONF
de départ.DISALLOWED_USER_AGENTS
dans CommonMiddleware
génère maintenant une exception PermissionDenied
au lieu de HttpResponseForbidden
afin que la vue handler403
soit appelée.HttpRequest.get_port()
a été ajoutée pour récupérer le port d’origine de la requête.json_dumps_params
a été ajouté à JsonResponse
pour permettre la transmission de paramètres nommés à l’appel json.dumps()
utilisé pour produire la réponse.BrokenLinkEmailsMiddleware
ignore dorénavant les erreurs 404 lorsque le référant est égal à l’URL demandée. Pour contourner le contrôle du référant vide déjà implémenté, certains robots Web définissent le référant à la même valeur que l’URL demandée.simple_tag()
peuvent maintenant stocker leur résultat dans une variable de gabarit en utilisant le paramètre as
.Context.setdefault()
a été ajoutée.DEBUG
pour les variables de contexte manquantes.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).firstof
permet de stocker son résultat dans une variable avec as
.Context.update()
peut maintenant être utilisée comme gestionnaire de contexte.DjangoTemplates
au moyen du réglage de gabarit OPTIONS
.timesince
et timeuntil
ont été améliorés pour tenir compte des années bissextiles pour de grands intervalles de temps.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 boucles for
.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.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 de login()
.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 to
include()
.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.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.
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ées can_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 champs DateTimeField
dans DatabaseOperations.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 en adapt_<type>field_value()
par cohérence avec les méthodes convert_<type>field_value()
.
Pour utiliser la nouvelle interrogation date
, les moteurs de base de données tiers pourraient devoir implémenter la méthode DatabaseOperations.datetime_cast_date_sql()
.
La méthode DatabaseOperations.time_extract_sql()
a été ajoutée. Elle appelle la méthode existante date_extract_sql()
. Cette méthode est surchargée par le moteur SQLite pour ajouter les interrogations horaires (heure, minute, seconde) aux champs TimeField
. Certains moteurs de base de données tiers pourraient avoir à faire de même.
La méthode DatabaseOperations.datetime_cast_sql()
(à ne pas confondre avec DatabaseOperations.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éfinir DatabaseFeatures.can_clone_databases = True
. Il peut être nécessaire d’ajuster DatabaseCreation.get_test_db_clone_settings()
.
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.
is_usable
des chargeurs de gabarit a été supprimé¶Les chargeurs de gabarit de Django exigeanient auparavant la présence d’un attribut is_usable
. Si un chargeur était configuré dans le réglage des gabarits et que cet attribut valait False
, le chargeur était ignoré en silence. En pratique, ce n’était utilisé que par le chargeur « egg » pour détecter si setuptools était installé. Cet attribut is_usable
est maintenant supprimé et le chargeur « egg » échoue au moment de l’exécution si setuptools n’est pas installé.
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 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.
Par conséquent, les URL attendues que assertRedirects
reçoit ne devraient généralement plus inclure la partie du protocole et du domaine des URL. Par exemple, self.assertRedirects(response, 'http://testserver/une-url/')
devrait être remplacé par self.assertRedirects(response, '/une-url/')
(sauf si la redirection contient réellement une URL absolue, bien sûr).
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
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.
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.
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.
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 the INFO
level and only active if DEBUG=True
.mail_admins
: filtered at the ERROR
level and only active if
DEBUG=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.
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()
.
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 :
USE_TZ
contient True
.connection.features.supports_timezones
.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.
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 %}
.
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
.
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 :
format_html()
.simple_tag
a besoin d’être échappé, utilisez escape()
ou conditional_escape()
.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()
.
__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.
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 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.
contrib.admin
have been moved into a
vendor/jquery
subdirectory.list_display
cells has changed from (None)
(or its translated equivalent) to -
(a
dash).django.http.responses.REASON_PHRASES
and
django.core.handlers.wsgi.STATUS_CODE_TEXT
have been removed. Use
Python’s stdlib instead: http.client.responses
for Python 3 and
httplib.responses for Python 2.ValuesQuerySet
and ValuesListQuerySet
have been removed.admin/base.html
template no longer sets
window.__admin_media_prefix__
or window.__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'
.ProcessFormView.get()
method to the new
FormMixin.get_context_data()
method. This may be
backwards incompatible if you have overridden the get_context_data()
method without calling super()
.django.contrib.sites.models.Site.domain
a été défini comme unique
.SimpleTestCase
tests anymore. You
can disable this behavior by setting the
allow_database_queries
class attribute
to True
on your test class.ResolverMatch.app_name
was changed to contain the full namespace path in
the case of nested namespaces. For consistency with
ResolverMatch.namespace
, the empty value is now an empty string instead
of None
.django.utils.functional.total_ordering()
has been
removed. It contained a workaround for a functools.total_ordering()
bug
in Python versions older than 2.7.3.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 a ValueError
.CharField
now strips input of leading and trailing
whitespace by default. This can be disabled by setting the new
strip
argument to False
."%%"
, may have a new msgid after makemessages
is run
(most likely the translation will be marked fuzzy). The new msgid
will be
marked "#, python-format"
.request.current_app
nor Context.current_app
are set, the
url
template tag will now use the namespace of the current request.
Set request.current_app
to None
if you don’t want to use a namespace
hint.SILENCED_SYSTEM_CHECKS
setting now silences messages of all
levels. Previously, messages of ERROR
level or higher were printed to the
console.FlatPage.enable_comments
field is removed from the FlatPageAdmin
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.setup_databases()
and the first
argument of teardown_databases()
changed. They used to be (old_names, mirrors)
tuples. Now they’re just
the first item, old_names
.LiveServerTestCase
attempts to find an
available port in the 8081-8179 range instead of just trying port 8081.ModelAdmin
vérifient maintenant les instances plutôt que les classes.django.db.models.fields.related
(private API) are moved from the
related
module to related_descriptors
and renamed as follows:ReverseSingleRelatedObjectDescriptor
is ForwardManyToOneDescriptor
SingleRelatedObjectDescriptor
is ReverseOneToOneDescriptor
ForeignRelatedObjectsDescriptor
is ReverseManyToOneDescriptor
ManyRelatedObjectsDescriptor
is ManyToManyDescriptor
handler404
view, it must
return a response with an HTTP 404 status code. Use
HttpResponseNotFound
or pass status=404
to the
HttpResponse
. Otherwise, APPEND_SLASH
won’t
work correctly with DEBUG=False
.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.
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.
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
url()
:
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
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.
weak
argument to django.dispatch.signals.Signal.disconnect()
has
been deprecated as it has no effect.check_aggregate_support()
method of
django.db.backends.base.BaseDatabaseOperations
has been deprecated and
will be removed in Django 2.0. The more general check_expression_support()
should be used instead.django.forms.extras
is deprecated. You can find
SelectDateWidget
in django.forms.widgets
(or simply django.forms
) instead.django.db.models.fields.add_lazy_relation()
is deprecated.django.contrib.auth.tests.utils.skipIfCustomUser()
decorator is
deprecated. With the test discovery changes in Django 1.6, the tests for
django.contrib
apps are no longer run as part of the user’s project.
Therefore, the @skipIfCustomUser
decorator is no longer needed to
decorate tests in django.contrib.auth
.exception
positional parameter.django.utils.feedgenerator.Atom1Feed.mime_type
and
django.utils.feedgenerator.RssFeed.mime_type
attributes are deprecated in
favor of content_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 of
Field.value_from_object()
.django.template.loaders.eggs.Loader
is deprecated as distributing
applications as eggs is not recommended.callable_obj
keyword argument to
SimpleTestCase.assertRaisesMessage()
is deprecated. Pass the callable as
a positional argument instead.allow_tags
attribute on methods of ModelAdmin
has been
deprecated. Use format_html()
,
format_html_join()
, or
mark_safe()
when constructing the method’s
return value instead.enclosure
keyword argument to SyndicationFeed.add_item()
is
deprecated. Use the new enclosures
argument which accepts a list of
Enclosure
objects instead of a single one.django.template.loader.LoaderOrigin
and
django.template.base.StringOrigin
aliases for
django.template.base.Origin
are deprecated.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.syncdb
command is removed.django.db.models.signals.pre_syncdb
and
django.db.models.signals.post_syncdb
is removed.allow_syncdb
on database routers is removed.migrate --run-syncdb
option.sql
, sqlall
,
sqlclear
, sqldropindexes
, and sqlindexes
, are removed.initial_data
fixtures and initial SQL
data is removed.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.IPAddressField
is removed. A stub field remains for
compatibility with historical migrations.AppCommand.handle_app()
is no longer supported.RequestSite
and get_current_site()
are no longer importable from
django.contrib.sites.models
.runfcgi
management command is removed.django.utils.datastructures.SortedDict
is removed.ModelAdmin.declared_fieldsets
is removed.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.BaseMemcachedCache._get_memcache_timeout()
method to
get_backend_timeout()
is removed.--natural
and -n
options for dumpdata
are removed.use_natural_keys
argument for serializers.serialize()
is removed.django.forms.forms.get_declared_fields()
is removed.SplitDateTimeWidget
with DateTimeField
is
removed.WSGIRequest.REQUEST
property is removed.django.utils.datastructures.MergeDict
is removed.zh-cn
and zh-tw
language codes are removed.django.utils.functional.memoize()
is removed.django.core.cache.get_cache
is removed.django.db.models.loading
a été supprimé.BaseCommand.requires_model_validation
is removed in favor of
requires_system_checks
. Admin validators is replaced by admin checks.ModelAdmin.validator_class
and default_validator_class
attributes
are removed.ModelAdmin.validate()
is removed.django.db.backends.DatabaseValidation.validate_field
is removed in
favor of the check_field
method.validate
management command is removed.django.utils.module_loading.import_by_path
is removed in favor of
django.utils.module_loading.import_string
.ssi
and url
template tags are removed from the future
template
tag library.django.utils.text.javascript_quote()
is removed.TEST_
, are no longer supported.ModelChoiceField
and
ModelMultipleChoiceField
is removed.RedirectView.permanent
attribute has changed from True
to False
.django.contrib.sitemaps.FlatPageSitemap
is removed in favor of
django.contrib.flatpages.sitemaps.FlatPageSitemap
.django.test.utils.TestTemplateLoader
a été supprimée.django.contrib.contenttypes.generic
a été supprimé.mars 30, 2019