Notes de publication de Django 1.10¶
1er août 2016
Bienvenue dans Django 1.10 !
Ces notes de publications couvrent les nouvelles fonctionnalités, ainsi que certaines modifications non rétro-compatibles dont il faut être au courant lors la mise à jour depuis Django 1.9 ou des versions plus anciennes. Nous avons abandonné certaines fonctionnalités qui ont atteint la fin de leur cycle d’obsolescence et nous avons commencé le processus d’obsolescence de certaines fonctionnalités.
Voir le guide Mise à jour de Django à une version plus récente si vous mettez à jour un projet existant.
Compatibilité Python¶
Comme pour Django 1.9, Django 1.10 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.
Quoi de neuf dans Django 1.10¶
Recherche plein texte avec PostgreSQL¶
django.contrib.postgres
inclut dorénavant une série de fonctions de base de données permettant d’exploiter le moteur de recherche plein texte. IL est possible de rechercher dans plusieurs champs de la base de données relationnelle, de combiner les recherches avec d’autres expressions de requête, d’utiliser différentes configurations de langue et de pondération, ainsi que de classer les résultats par pertinence.
Elle inclut aussi la prise en charge des trigrammes, en utilisant la requête trigram_similar
et les expressions TrigramSimilarity
et TrigramDistance
.
Intergiciels nouveau style¶
A new style of middleware is introduced to
solve the lack of strict request/response layering of the old-style of
middleware described in DEP 0005.
You’ll need to adapt old, custom middleware and
switch from the MIDDLEWARE_CLASSES
setting to the new MIDDLEWARE
setting to take advantage of the improvements.
Prise en charge officielle des noms d’utilisateurs Unicode¶
The User
model in django.contrib.auth
originally only accepted ASCII letters and numbers in usernames. Although it
wasn’t a deliberate choice, Unicode characters have always been accepted when
using Python 3.
The username validator now explicitly accepts Unicode characters by default on Python 3 only.
Custom user models may use the new
ASCIIUsernameValidator
or
UnicodeUsernameValidator
.
Fonctionnalités mineures¶
django.contrib.admin
¶
- Pour les sites fonctionnant dans un sous-chemin,
l'URL par défaut du lien « Voir sur le site »
au sommet de chaque page du site d’administration prend désormais en compterequest.META['SCRIPT_NAME']
s’il est défini au lieu de/
. - Le message de succès apparaissant après l’ajout ou l’édition d’un objet contient maintenant un lien vers le formulaire de modification de l’objet concerné.
- Tout le code JavaScript en ligne a été enlevé afin de pouvoir activer l’en-tête HTTP
Content-Security-Policy
si souhaité. - Le nouvel attribut
InlineModelAdmin.classes
permet d’indiquer des classes pour les sous-formulaires en ligne. Ces derniers, s’ils possèdent une classecollapse
, sont initialement repliés et leur en-tête contient un petit lien « Afficher ». - If a user doesn’t have the add permission, the
object-tools
block on a model’s changelist will now be rendered (without the add button). This makes it easier to add custom tools in this case. - Le modèle
LogEntry
stocke dorénavant ses messages de modification dans une structure JSON afin que les messages puissent être dynamiquement traduits dans la langue active. Une nouvelle méthodeLogEntry.get_change_message()
constitue maintenant la manière privilégiée d’obtenir les messages de modification. - Les objets sélectionnés pour les champs dans
ModelAdmin.raw_id_fields
ont maintenant un lien vers le formulaire de modification des objets. - Les choix « Aucune date » et « Possède une date » on été ajoutés pour le filtre
DateFieldListFilter
dans le cas où le champ peut contenir la valeur nulle. - La bibliothèque jQuery incluse dans l’administration a été mise à jour de 2.1.4 vers 2.2.3.
django.contrib.auth
¶
- La prise en charge du hachage de mot de passe Argon2 a été ajoutée. Il devrait être préféré à PBKDF2, mais il n’est cependant pas par défaut car il nécessite une bibliothèque tierce.
- Le nombre d’itérations par défaut du hachage des mots de passe PBKDF2 a été augmenté de 25%. 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. - The
django.contrib.auth.views.logout()
view sends « no-cache » headers to prevent an issue where Safari caches redirects and prevents a user from being able to log out. - Added the optional
backend
argument todjango.contrib.auth.login()
to allow using it without credentials. - The new
LOGOUT_REDIRECT_URL
setting controls the redirect of thedjango.contrib.auth.views.logout()
view, if the view doesn’t get anext_page
argument. - The new
redirect_authenticated_user
parameter for thedjango.contrib.auth.views.login()
view allows redirecting authenticated users visiting the login page. - Les nouveaux moteurs d’authentification
AllowAllUsersModelBackend
etAllowAllUsersRemoteUserBackend
ignorent la valeur deUser.is_active
, alors queModelBackend
etRemoteUserBackend
rejettent dorénavant les utilisateurs inactifs.
django.contrib.gis
¶
- Les requêtes de distance acceptent maintenant des expressions comme paramètre de valeur de distance.
- La nouvelle propriété
GEOSGeometry.unary_union
calcule l’union de tous les éléments d’un objet géométrique. - Le prédicat binaire
GEOSGeometry.covers()
a été ajouté. - La méthode
GDALBand.statistics()
ainsi que les attributsmean
etstd
ont été ajoutés. - L’agrégat
MakeLine
et la fonctionGeoHash
ont été ajoutés pour Spatialite. - Les fonctions
Difference
,Intersection
etSymDifference
ont été ajoutées pour MySQL. - La possibilité d’instancier des géométries GEOS vides a été ajoutée.
- Les nouvelles propriétés
trim
etprecision
deWKTWriter
permettent de contrôler la précision de la partie fractionnelle des coordonnées produites au format WKT. - Les propriétés
LineString.closed
etMultiLineString.closed
ont été ajoutées. - Le sérialiseur GeoJSON produit dorénavant la clé primaire des objets dans le dictionnaire
properties
si aucun champ spécifique n’est indiqué. - La possibilité de dupliquer des données d’entrées de la méthode
GDALBand.data()
a été ajoutée. Les données de bande peuvent maintenant être mises à jour efficacement avec des valeurs répétées. - Les fonctions de base de données
IsValid
etMakeValid
ont été ajoutées, de même que la requêteisvalid
, le tout pour PostGIS. Cela permet de filtrer et de réparer des objets géométriques non valides du côté de la base de données. - La prise en charge des objets matriciels (raster) a été ajoutée pour toutes les requêtes spatiales.
django.contrib.postgres
¶
- Par commodité,
HStoreField
force dorénavant ses clés et valeurs en texte.
django.contrib.sessions
¶
- La commande d’administration
clearsessions
supprime dorénavant les sessions basées sur des fichiers.
django.contrib.sites
¶
- Le modèle
Site
prend dorénavant en charge les clés naturelles.
django.contrib.staticfiles
¶
- La balise de gabarit
static
utilise maintenantdjango.contrib.staticfiles
si cette application est installée. C’est particulièrement utile pour les applications tierces qui peuvent dorénavant toujours utiliser{% load static %}
(au lieu de{% load staticfiles %}
ou{% load static from staticfiles %}
) et ne plus se soucier de savoir si l’applicationstaticfiles
est installée ou non. - You can more easily customize
the
collectstatic --ignore
option with a customAppConfig
.
Cache¶
- Le moteur de cache basé sur des fichiers utilise dorénavant le protocole de « pickling » le plus élevé.
CSRF¶
- La vue par défaut
CSRF_FAILURE_VIEW
,views.csrf.csrf_failure()
, accepte dorénavant un paramètre facultatiftemplate_name
, valant'403_csrf.html'
par défaut, pour contrôler le gabarit utilisé pour produire la page. - Afin de protéger contre les attaques BREACH, le mécanisme de protection CSRF modifie dorénavant la valeur du jeton de formulaire lors de chaque requête (tout en conservant une valeur secrète stable pouvant être utilisée pour valider les différents jetons).
Moteurs de base de données¶
- La soustraction de données temporelles a été unifiée pour tous les moteurs.
- Si la base de données le gère, les moteurs peuvent définir
DatabaseFeatures.can_return_ids_from_bulk_insert=True
et implémenterDatabaseOperations.fetch_returned_insert_ids()
pour définir les clés primaires des objets créés parQuerySet.bulk_create()
. - Des paramètres nommés ont été ajoutés aux méthodes
as_sql()
de diverses expressions (Func
,When
,Case
etOrderBy
) pour permettre aux moteurs de base de données de les personnaliser sans devoir toucher àself
, ce qui est peu sûr lors de l’emploi de plusieurs moteurs de base de données. Voir les paramètresarg_joiner
et**extra_context
deFunc.as_sql()
pour un exemple.
Stockage de fichier¶
- Les moteurs de stockage présentent dorénavant une API consciente du fuseau horaire avec de nouvelles méthodes
get_accessed_time()
,get_created_time()
etget_modified_time()
. Elles renvoient un objetdatetime
conscient du fuseau horaire siUSE_TZ
vautTrue
et un objetdatetime
« naïf » dans le fuseau horaire local dans le cas contraire. - La nouvelle méthode
Storage.generate_filename()
facilite l’implémentation de stockages personnalisés qui n’utilisent pas les appelsos.path
qui se trouvaient précédemment dansFileField
.
Formulaires¶
- Les contenus de la classe
Media
des formulaires et composants sont dorénavant servis pardjango.contrib.staticfiles
quand cette application est installée. - La balise
<input>
rendue parCharField
inclut maintenant un attributminlength
si le champ possède un attributmin_length
. - Les champs de formulaire obligatoires possèdent dorénavant l’attribut HTML
required
. Il est possible de désactiver cela en définissant l’attributForm.use_required_attribute
àFalse
. L’attributrequired
n’est pas ajouté aux formulaires groupés car la validation des navigateurs n’est pas toujours correcte quand on ajoute ou qu’on supprime de tels formulaires.
Internationalisation¶
- La fonction utilitaire
i18n_patterns()
peut dorénavant être utilisée dans une configuration d’URL racine désignée parrequest.urlconf
. - En définissant le nouveau paramètre
prefix_default_language
dei18n_patterns()
àFalse
, vous pouvez autoriser l’accès à la langue par défaut sans préfixe d’URL. set_language()
renvoie désormais un code de statut 204 (Pas de contenu) pour les requêtes AJAX lorsquePOST
ouGET
ne contiennent pas de paramètrenext
.- Les vues fondées sur des classes
JavaScriptCatalog
etJSONCatalog
remplacent les vues fondées sur des fonctionsjavascript_catalog()
etjson_catalog()
. Les nouvelles vues sont presque équivalentes aux anciennes sauf que par défaut les nouvelles vues collectent toutes les chaînes JavaScript de toutes les applications installées dans le domaine de traductiondjangojs
au lieu de seulement récolter les chaînes JavaScript provenant des cheminsLOCALE_PATHS
.
Commandes d’administration¶
call_command()
renvoie dorénavant la valeur reçue de la méthodecommand.handle()
.- La nouvelle option
check --fail-level
permet de définir le niveau de message qui produira la sortie de la commande avec un code d’état différent de zéro. - La nouvelle option
makemigrations --check
fait quitter la commande avec un statut différent de 0 lorsque des modifications de modèles sans migration correspondante sont détectés. makemigrations
affiche dorénavant le chemin vers les fichiers de migration qu’elle génère.- L’option
shell --interface
accepte dorénavantpython
pour forcer l’utilisation de l’interpréteur Python « pur ». - La nouvelle option
shell --command
permet d’exécuter une commande depuis Django et quitter, au lieu d’ouvrir le shell interactif. dumpdata
émet un avertissement si un modèle mandataire est spécifié (qui ne produit aucun résultat) sans son parent concret.- Le nouvel attribut
BaseCommand.requires_migrations_checks
peut être défini àTrue
si vous souhaitez que la commande affiche un avertissement, comme le faitrunserver
, quand le jeu de migrations sur disque ne correspond pas aux migrations dans la base de données. - Pour aider dans les tests,
call_command()
accepte dorénavant un objet commande comme premier paramètre. - The
shell
command supports tab completion on systems usinglibedit
, e.g. macOS. - La commande
inspectdb
permet de choisir les tables à inspecter en indiquant leur nom en paramètre.
Migrations¶
- La prise en charge de la sérialisation d’objets
enum.Enum
a été ajoutée. - Le paramètre
elidable
a été ajouté aux opérationsRunSQL
etRunPython
pour indiquer qu’elles doivent être supprimées lors de la fusion des migrations. - La prise en charge des migrations non atomiques a été ajoutée en définissant l’attribut
atomic
d’une classeMigration
. - The
migrate
andmakemigrations
commands now check for a consistent migration history. If they find some unapplied dependencies of an applied migration,InconsistentMigrationHistory
is raised. - Les signaux
pre_migrate()
etpost_migrate()
propagent dorénavant leplan
et lesapps
de la migration.
Modèles¶
- Les clés étrangères inverses de modèles mandataires sont dorénavant propagées vers leur classe concrète. La relation inverse liée par une clé
ForeignKey
pointant vers un modèle mandataire est dorénavant accessible sous forme de descripteur sur la classe de modèle mandatée et peut être référencée dans des filtres de requête. - La nouvelle méthode
Field.rel_db_type()
renvoie le type de donnée de la colonne de la base de données, tel queForeignKey
etOneToOneField
qui pointent vers un autre champ. - L’attribut de classe
arity
a été ajouté àFunc
. Cet attribut est utilisé pour définir le nombre de paramètres acceptés par la fonction. - Le nouveau champ
BigAutoField
est très similaire àAutoField
sauf qu’il garantit la couverture des nombres de1
à9223372036854775807
. QuerySet.in_bulk()
peut être appelée sans paramètre pour renvoyer tous les objets du jeu de requête.related_query_name
prend désormais en charge l’extrapolation de l’étiquette d’application et de la classe en utilisant les chaînes'%(app_label)s'
et'%(class)s'
.- Il est dorénavant autorisé de surcharger des champs de modèles hérités de classes de base abstraites.
- La fonction
prefetch_related_objects()
est maintenant une API publique. QuerySet.bulk_create()
définit la clé primaire des objets quand on l’utilise avec PostgreSQL.- La fonction de base de données
Cast
a été ajoutée. - Un modèle mandataire peut dorénavant hériter de plusieurs modèles mandataires partageant une classe parente commune non abstraite.
- Added
Extract
functions to extract datetime components as integers, such as year and hour. - Added
Trunc
functions to truncate a date or datetime to a significant component. They enable queries like sales-per-day or sales-per-hour. Model.__init__()
définit dorénavant les valeurs de champs virtuels à partir de ses paramètres nommés.- Les nouvelles options
Meta.base_manager_name
etMeta.default_manager_name
permettent de contrôler respectivement les attributs_base_manager
et_default_manager
.
Requêtes et réponses¶
request.user
a été ajoutée à la vue de débogage.- Les méthodes
readable()
etseekable()
ont été ajoutées àHttpResponse
pour en faire une instance d’objet de type flux et permettre de l’adapter dans une classeio.TextIOWrapper
. - Added the
HttpRequest.content_type
andcontent_params
attributes which are parsed from theCONTENT_TYPE
header. - L’analyseur de
request.COOKIES
a été simplifié pour mieux correspondre au comportement des navigateurs.request.COOKIES
peut dorénavant contenir des cookies non valides selon la RFC 6265 mais qui peuvent quand même être définis viadocument.cookie
.
Sérialisation¶
django.core.serializers.json.DjangoJSONEncoder
sait dorénavant sérialiser des chaînes différées, typiquement utilisées pour du contenu traduisible.
Gabarits¶
- L’option
autoescape
a été ajoutée au moteurDjangoTemplates
et à la classeEngine
. - Les opérateurs de comparaison
is
etis not
ont été ajoutée à la baliseif
. dictsort
peut maintenant trier une liste de listes par un élément d’un indice donné.- Le processeur de contexte
debug()
contient les requêtes de tous les alias de base de données, et non plus seulement celles de l’alias par défaut. - Les balises de gabarit
extends
etinclude
prennent dorénavant en charge des chemins relatifs pour leurs paramètres sous forme de chaîne.
Tests¶
- Pour mieux éviter les bugs,
TestCase
contrôle dorénavant les contraintes de base de données différables à la fin de chaque test. - Les tests et les cas de test peuvent être marqués par des étiquettes et exécutés de manière sélective grâce aux nouvelles options
test --tag
ettest --exclude-tag
. - Il est maintenant possible de se connecter et d’utiliser des sessions avec le client de test même si
django.contrib.sessions
ne se trouve pas dansINSTALLED_APPS
.
URL¶
- Un ajout à
django.setup()
permet à la résolution d’URL qui intervient en dehors du cycle requête/réponse (par ex. dans les commandes d’administration et les scripts autonomes) de prendre en compteFORCE_SCRIPT_NAME
lorsque celui-ci est défini.
Validateurs¶
URLValidator
limite dorénavant la longueur des parties de noms de domaine à 63 caractères et la longueur totale des noms de domaines à 253 caractères, en accord avec la RFC 1034.int_list_validator()
accepte dorénavant un paramètre booléen facultatifallow_negative
, valantFalse
par défaut, pour autoriser les entiers négatifs.
Changements incompatibles avec les anciennes versions dans Django 1.10¶
Avertissement
En plus des modifications détaillées dans cette section, prenez soin de parcourir les Fonctionnalités supprimées dans 1.10 é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¶
- Le champ GIS
AreaField
utilise un type numérique non spécifié qui pourrait être en pratique tout type numérique Python. Les valeursdecimal.Decimal
provenant de la base de données sont dorénavant converties enfloat
pour faciliter leur combinaison avec des valeurs utilisées par les bibliothèques GIS. - In order to enable temporal subtraction you must set the
supports_temporal_subtraction
database feature flag toTrue
and implement theDatabaseOperations.subtract_temporals()
method. This method should return the SQL and parameters required to compute the difference in microseconds between thelhs
andrhs
arguments in the datatype used to storeDurationField
.
_meta.get_fields()
returns consistent reverse fields for proxy models¶
Before Django 1.10, the get_fields()
method returned different reverse fields when called on a proxy model compared
to its proxied concrete class. This inconsistency was fixed by returning the
full set of fields pointing to a concrete class or one of its proxies in both
cases.
AbstractUser.username
max_length
increased to 150¶
A migration for django.contrib.auth.models.User.username
is included.
If you have a custom user model inheriting from AbstractUser
, you’ll need
to generate and apply a database migration for your user model.
We considered an increase to 254 characters to more easily allow the use of
email addresses (which are limited to 254 characters) as usernames but rejected
it due to a MySQL limitation. When using the utf8mb4
encoding (recommended
for proper Unicode support), MySQL can only create unique indexes with 191
characters by default. Therefore, if you need a longer length, please use a
custom user model.
If you want to preserve the 30 character limit for usernames, use a custom form when creating a user or changing usernames:
from django.contrib.auth.forms import UserCreationForm
class MyUserCreationForm(UserCreationForm):
username = forms.CharField(
max_length=30,
help_text="Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.",
)
If you wish to keep this restriction in the admin, set UserAdmin.add_form
to use this form:
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
class UserAdmin(BaseUserAdmin):
add_form = MyUserCreationForm
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Abandon de la prise en charge de PostgreSQL 9.1¶
La prise en charge de PostgreSQL 9.1 par le projet amont se termine en septembre 2016. Par conséquent, Django 1.10 a défini la version 9.2 comme la version minimum de PostgreSQL officiellement prise en charge.
La sortie de runserver
passe par l’infrastructure de journalisation¶
Request and response handling of the runserver
command is sent to the
django.server logger instead of to sys.stderr
. If you
disable Django’s logging configuration or override it with your own, you’ll
need to add the appropriate logging configuration if you want to see that
output:
LOGGING = {
# ...
"formatters": {
"django.server": {
"()": "django.utils.log.ServerFormatter",
"format": "[%(server_time)s] %(message)s",
}
},
"handlers": {
"django.server": {
"level": "INFO",
"class": "logging.StreamHandler",
"formatter": "django.server",
},
},
"loggers": {
"django.server": {
"handlers": ["django.server"],
"level": "INFO",
"propagate": False,
}
},
}
auth.CustomUser
and auth.ExtensionUser
test models were removed¶
Since the introduction of migrations for the contrib apps in Django 1.8, the tables of these custom user test models were not created anymore making them unusable in a testing context.
Apps registry is no longer auto-populated when unpickling models outside of Django¶
The apps registry is no longer auto-populated when unpickling models. This was
added in Django 1.7.2 as an attempt to allow unpickling models outside of
Django, such as in an RQ worker, without calling django.setup()
, but it
creates the possibility of a deadlock. To adapt your code in the case of RQ,
you can provide your own worker script
that calls django.setup()
.
Removed null assignment check for non-null foreign key fields¶
In older versions, assigning None
to a non-nullable ForeignKey
or
OneToOneField
raised ValueError('Cannot assign None: "model.field" does
not allow null values.')
. For consistency with other model fields which don’t
have a similar check, this check is removed.
Removed weak password hashers from the default PASSWORD_HASHERS
setting¶
Django 0.90 stored passwords as unsalted MD5. Django 0.91 added support for salted SHA1 with automatic upgrade of passwords when a user logs in. Django 1.4 added PBKDF2 as the default password hasher.
If you have an old Django project with MD5 or SHA1 (even salted) encoded
passwords, be aware that these can be cracked fairly easily with today’s
hardware. To make Django users acknowledge continued use of weak hashers, the
following hashers are removed from the default PASSWORD_HASHERS
setting:
"django.contrib.auth.hashers.SHA1PasswordHasher"
"django.contrib.auth.hashers.MD5PasswordHasher"
"django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher"
"django.contrib.auth.hashers.UnsaltedMD5PasswordHasher"
"django.contrib.auth.hashers.CryptPasswordHasher"
Consider using a wrapped password hasher to
strengthen the hashes in your database. If that’s not feasible, add the
PASSWORD_HASHERS
setting to your project and add back any hashers
that you need.
You can check if your database has any of the removed hashers like this:
from django.contrib.auth import get_user_model
User = get_user_model()
# Unsalted MD5/SHA1:
User.objects.filter(password__startswith="md5$$")
User.objects.filter(password__startswith="sha1$$")
# Salted MD5/SHA1:
User.objects.filter(password__startswith="md5$").exclude(password__startswith="md5$$")
User.objects.filter(password__startswith="sha1$").exclude(password__startswith="sha1$$")
# Crypt hasher:
User.objects.filter(password__startswith="crypt$$")
from django.db.models import CharField
from django.db.models.functions import Length
CharField.register_lookup(Length)
# Unsalted MD5 passwords might not have an 'md5$$' prefix:
User.objects.filter(password__length=32)
Field.get_prep_lookup()
and Field.get_db_prep_lookup()
methods are removed¶
If you have a custom field that implements either of these methods, register a custom lookup for it. For example:
from django.db.models import Field
from django.db.models.lookups import Exact
class MyField(Field): ...
class MyFieldExact(Exact):
def get_prep_lookup(self):
# do_custom_stuff_for_myfield
...
MyField.register_lookup(MyFieldExact)
django.contrib.gis
¶
- Support for SpatiaLite < 3.0 and GEOS < 3.3 is dropped.
- The
add_postgis_srs()
backwards compatibility alias fordjango.contrib.gis.utils.add_srs_entry()
is removed. - On Oracle/GIS, the
Area
aggregate function now returns afloat
instead ofdecimal.Decimal
. (It’s still wrapped in a measure of square meters.) - The default
GEOSGeometry
representation (WKT output) is trimmed by default. That is, instead ofPOINT (23.0000000000000000 5.5000000000000000)
, you’ll getPOINT (23 5.5)
.
Maximum size of a request body and the number of GET/POST parameters is limited¶
Two new settings help mitigate denial-of-service attacks via large requests:
DATA_UPLOAD_MAX_MEMORY_SIZE
limits the size that a request body may be. File uploads don’t count toward this limit.DATA_UPLOAD_MAX_NUMBER_FIELDS
limits the number of GET/POST parameters that are parsed.
Applications that receive unusually large form posts may need to tune these settings.
Divers¶
- The
repr()
of aQuerySet
is wrapped in<QuerySet >
to disambiguate it from a plain list when debugging. utils.version.get_version()
returns PEP 440 compliant release candidate versions (e.g. “1.10rc1” instead of “1.10c1”).- CSRF token values are now required to be strings of 64 alphanumerics; values of 32 alphanumerics, as set by older versions of Django by default, are automatically replaced by strings of 64 characters. Other values are considered invalid. This should only affect developers or users who replace these tokens.
- The
LOGOUT_URL
setting is removed as Django hasn’t made use of it since pre-1.0. If you use it in your project, you can add it to your project’s settings. The default value was'/accounts/logout/'
. - Objects with a
close()
method such as files and generators passed toHttpResponse
are now closed immediately instead of when the WSGI server callsclose()
on the response. - A redundant
transaction.atomic()
call inQuerySet.update_or_create()
is removed. This may affect query counts tested byTransactionTestCase.assertNumQueries()
. - Support for
skip_validation
inBaseCommand.execute(**options)
is removed. Useskip_checks
(added in Django 1.7) instead. loaddata
now raises aCommandError
instead of showing a warning when the specified fixture file is not found.- Instead of directly accessing the
LogEntry.change_message
attribute, it’s now better to call theLogEntry.get_change_message()
method which will provide the message in the current language. - The default error views now raise
TemplateDoesNotExist
if a nonexistenttemplate_name
is specified. - The unused
choices
keyword argument of theSelect
andSelectMultiple
widgets”render()
method is removed. Thechoices
argument of therender_options()
method is also removed, makingselected_choices
the first argument. - Tests that violate deferrable database constraints will now error when run on a database that supports deferrable constraints.
- Built-in management commands now use indexing of keys in
options
, e.g.options['verbosity']
, instead ofoptions.get()
and no longer perform any type coercion. This could be a problem if you’re calling commands usingCommand.execute()
(which bypasses the argument parser that sets a default value) instead ofcall_command()
. Instead of callingCommand.execute()
, pass the command object as the first argument tocall_command()
. ModelBackend
andRemoteUserBackend
now reject inactive users. This means that inactive users can’t login and will be logged out if they are switched fromis_active=True
toFalse
. If you need the previous behavior, use the newAllowAllUsersModelBackend
orAllowAllUsersRemoteUserBackend
inAUTHENTICATION_BACKENDS
instead.- In light of the previous change, the test client’s
login()
method no longer always rejects inactive users but instead delegates this decision to the authentication backend.force_login()
also delegates the decision to the authentication backend, so if you’re using the default backends, you need to use an active user. django.views.i18n.set_language()
may now return a 204 status code for AJAX requests.- The
base_field
attribute ofRangeField
is now a type of field, not an instance of a field. If you have created a custom subclass ofRangeField
, you should change thebase_field
attribute. - Middleware classes are now initialized when the server starts rather than during the first request.
- If you override
is_authenticated()
oris_anonymous()
in a custom user model, you must convert them to attributes or properties as described in the deprecation note. - When using
ModelAdmin.save_as=True
, the « Save as new » button now redirects to the change view for the new object instead of to the model’s changelist. If you need the previous behavior, set the newModelAdmin.save_as_continue
attribute toFalse
. - Required form fields now have the
required
HTML attribute. Set theForm.use_required_attribute
attribute toFalse
to disable it. You could also add thenovalidate
attribute to<form>
if you don’t want browser validation. To disable therequired
attribute on custom widgets, override theWidget.use_required_attribute()
method. - The WSGI handler no longer removes content of responses from
HEAD
requests or responses with astatus_code
of 100-199, 204, or 304. Most web servers already implement this behavior. Responses retrieved using the Django test client continue to have these « response fixes » applied. Model.__init__()
now receivesdjango.db.models.DEFERRED
as the value of deferred fields.- The
Model._deferred
attribute is removed as dynamic model classes when usingQuerySet.defer()
andonly()
is removed. Storage.save()
no longer replaces'\'
with'/'
. This behavior is moved toFileSystemStorage
since this is a storage specific implementation detail. Any Windows user with a custom storage implementation that relies on this behavior will need to implement it in the custom storage’ssave()
method.- Private
FileField
methodsget_directory_name()
andget_filename()
are no longer called (and are now deprecated) which is a backwards incompatible change for users overriding those methods on custom fields. To adapt such code, overrideFileField.generate_filename()
orStorage.generate_filename()
instead. It might be possible to useupload_to
also. - The subject of mail sent by
AdminEmailHandler
is no longer truncated at 989 characters. If you were counting on a limited length, truncate the subject yourself. - Private expressions
django.db.models.expressions.Date
andDateTime
are removed. The newTrunc
expressions provide the same functionality. - The
_base_manager
and_default_manager
attributes are removed from model instances. They remain accessible on the model class. - Accessing a deleted field on a model instance, e.g. after
del obj.field
, reloads the field’s value instead of raisingAttributeError
. - If you subclass
AbstractBaseUser
and overrideclean()
, be sure it callssuper()
.AbstractBaseUser.normalize_username()
is called in a newAbstractBaseUser.clean()
method. - Private API
django.forms.models.model_to_dict()
returns a queryset rather than a list of primary keys forManyToManyField
s. - If
django.contrib.staticfiles
is installed, thestatic
template tag uses thestaticfiles
storage to construct the URL rather than simply joining the value withSTATIC_ROOT
. The new approach encodes the URL, which could be backwards-incompatible in cases such as including a fragment in a path, e.g.{% static 'img.svg#fragment' %}
, since the#
is encoded as%23
. To adapt, move the fragment outside the template tag:{% static 'img.svg' %}#fragment
. - When
USE_L10N
isTrue
, localization is now applied for thedate
andtime
filters when no format string is specified. TheDATE_FORMAT
andTIME_FORMAT
specifiers from the active locale are used instead of the settings of the same name.
Features deprecated in 1.10¶
Direct assignment to a reverse foreign key or many-to-many relation¶
Instead of assigning related objects using direct assignment:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
Use the set()
method
added in Django 1.9:
>>> e.related_set.set([obj1, obj2, obj3])
Cela évite de la confusion concernant l’enregistrement implicite provoqué par l’attribution directe.
Non-timezone-aware Storage
API¶
The old, non-timezone-aware methods accessed_time()
, created_time()
,
and modified_time()
are deprecated in favor of the new get_*_time()
methods.
Third-party storage backends should implement the new methods and mark the old
ones as deprecated. Until then, the new get_*_time()
methods on the base
Storage
class convert datetime
s from
the old methods as required and emit a deprecation warning as they do so.
Third-party storage backends may retain the old methods as long as they wish to support earlier versions of Django.
django.contrib.gis
¶
- The
get_srid()
andset_srid()
methods ofGEOSGeometry
are deprecated in favor of thesrid
property. - The
get_x()
,set_x()
,get_y()
,set_y()
,get_z()
, andset_z()
methods ofPoint
are deprecated in favor of thex
,y
, andz
properties. - The
get_coords()
andset_coords()
methods ofPoint
are deprecated in favor of thetuple
property. - The
cascaded_union
property ofMultiPolygon
is deprecated in favor of theunary_union
property. - The
django.contrib.gis.utils.precision_wkt()
function is deprecated in favor ofWKTWriter
.
CommaSeparatedIntegerField
model field¶
CommaSeparatedIntegerField
is deprecated in favor of
CharField
with the
validate_comma_separated_integer_list()
validator:
from django.core.validators import validate_comma_separated_integer_list
from django.db import models
class MyModel(models.Model):
numbers = models.CharField(..., validators=[validate_comma_separated_integer_list])
If you’re using Oracle, CharField
uses a different database field type
(NVARCHAR2
) than CommaSeparatedIntegerField
(VARCHAR2
). Depending
on your database settings, this might imply a different encoding, and thus a
different length (in bytes) for the same contents. If your stored values are
longer than the 4000 byte limit of NVARCHAR2
, you should use TextField
(NCLOB
) instead. In this case, if you have any queries that group by the
field (e.g. annotating the model with an aggregation or using distinct()
)
you’ll need to change them (to defer the field).
__search
query lookup¶
The search
lookup, which supports MySQL only and is extremely limited in
features, is deprecated. Replace it with a custom lookup:
from django.db import models
class Search(models.Lookup):
lookup_name = "search"
def as_mysql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return "MATCH (%s) AGAINST (%s IN BOOLEAN MODE)" % (lhs, rhs), params
models.CharField.register_lookup(Search)
models.TextField.register_lookup(Search)
Using User.is_authenticated()
and User.is_anonymous()
as methods¶
The is_authenticated()
and is_anonymous()
methods of
AbstractBaseUser
and
AnonymousUser
classes are now
properties. They will still work as methods until Django 2.0, but all usage
in Django now uses attribute access.
For example, if you use
AuthenticationMiddleware
and want
to know whether the user is currently logged-in you would use:
if request.user.is_authenticated:
... # Do something for logged-in users.
else:
... # Do something for anonymous users.
instead of request.user.is_authenticated()
.
This change avoids accidental information leakage if you forget to call the method, e.g.:
if request.user.is_authenticated:
return sensitive_information
If you override these methods in a custom user model, you must change them to properties or attributes.
Django uses a CallableBool
object to allow these attributes to work as both
a property and a method. Thus, until the deprecation period ends, you cannot
compare these properties using the is
operator. That is, the following
won’t work:
if request.user.is_authenticated is True:
...
The « escape » half of django.utils.safestring
¶
The mark_for_escaping()
function and the classes it uses: EscapeData
,
EscapeBytes
, EscapeText
, EscapeString
, and EscapeUnicode
are
deprecated.
As a result, the « lazy » behavior of the escape
filter (where it would
always be applied as the last filter no matter where in the filter chain it
appeared) is deprecated. The filter will change to immediately apply
conditional_escape()
in Django 2.0.
Divers¶
- The
makemigrations --exit
option is deprecated in favor of themakemigrations --check
option. django.utils.functional.allow_lazy()
is deprecated in favor of the newkeep_lazy()
function which can be used with a more natural decorator syntax.- The
shell --plain
option is deprecated in favor of-i python
or--interface python
. - Importing from the
django.core.urlresolvers
module is deprecated in favor of its new location,django.urls
. - The template
Context.has_key()
method is deprecated in favor ofin
. - The private attribute
virtual_fields
ofModel._meta
is deprecated in favor ofprivate_fields
. - The private keyword arguments
virtual_only
inField.contribute_to_class()
andvirtual
inModel._meta.add_field()
are deprecated in favor ofprivate_only
andprivate
, respectively. - The
javascript_catalog()
andjson_catalog()
views are deprecated in favor of class-based viewsJavaScriptCatalog
andJSONCatalog
. - In multi-table inheritance, implicit promotion of a
OneToOneField
to aparent_link
is deprecated. Addparent_link=True
to such fields. - The private API
Widget._format_value()
is made public and renamed toformat_value()
. The old name will work through a deprecation period. - Private
FileField
methodsget_directory_name()
andget_filename()
are deprecated in favor of performing this work inStorage.generate_filename()
). - Old-style middleware that uses
settings.MIDDLEWARE_CLASSES
are deprecated. Adapt old, custom middleware and use the newMIDDLEWARE
setting.
Fonctionnalités supprimées dans 1.10¶
Ces fonctionnalités ont atteint la fin de leur cycle d’obsolescence et sont supprimées dans Django 1.10. Voir Features deprecated in 1.8 pour les détails, ainsi que pour savoir comment supprimer l’utilisation de ces fonctionnalités.
- Support for calling a
SQLCompiler
directly as an alias for calling itsquote_name_unless_alias
method is removed. - The
cycle
andfirstof
template tags are removed from thefuture
template tag library. django.conf.urls.patterns()
is removed.- Support for the
prefix
argument todjango.conf.urls.i18n.i18n_patterns()
is removed. SimpleTestCase.urls
is removed.- Using an incorrect count of unpacked values in the
for
template tag raises an exception rather than failing silently. - The ability to
reverse()
URLs using a dotted Python path is removed. - The ability to use a dotted Python path for the
LOGIN_URL
andLOGIN_REDIRECT_URL
settings is removed. - La prise en charge de
optparse
pour les commandes d’administration personnalisées est supprimée. - La classe
django.core.management.NoArgsCommand
est supprimée. - Le module
django.core.context_processors
est supprimé. - Le module
djangodb.models.sql.aggregates
est supprimé. - Le module
django.contrib.gis.db.models.sql.aggregates
est supprimé. - Les méthodes et propriétés suivantes de
django.db.sql.query.Query
sont supprimées :- Propriétés :
aggregates
etaggregate_select
- Méthodes :
add_aggregate
,set_aggregate_mask
etappend_aggregate_mask
.
- Propriétés :
django.template.resolve_variable
est supprimée.- Les API privées suivantes sont supprimées de
django.db.models.options.Options
(Model._meta
) :get_field_by_name()
get_all_field_names()
get_fields_with_model()
get_concrete_fields_with_model()
get_m2m_with_model()
get_all_related_objects()
get_all_related_objects_with_model()
get_all_related_many_to_many_objects()
get_all_related_m2m_objects_with_model()
- Le paramètre
error_message
dedjango.forms.RegexField
est supprimé. - The
unordered_list
filter no longer supports old style lists. - Support for string
view
arguments tourl()
is removed. - The backward compatible shim to rename
django.forms.Form._has_changed()
tohas_changed()
is removed. - The
removetags
template filter is removed. - The
remove_tags()
andstrip_entities()
functions indjango.utils.html
is removed. - The
is_admin_site
argument todjango.contrib.auth.views.password_reset()
is removed. django.db.models.field.subclassing.SubfieldBase
is removed.django.utils.checksums
is removed.- The
original_content_type_id
attribute ondjango.contrib.admin.helpers.InlineAdminForm
is removed. - The backwards compatibility shim to allow
FormMixin.get_form()
to be defined with no default value for itsform_class
argument is removed. - The following settings are removed, and you must upgrade to the
TEMPLATES
setting:ALLOWED_INCLUDE_ROOTS
TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_DEBUG
TEMPLATE_DIRS
TEMPLATE_LOADERS
TEMPLATE_STRING_IF_INVALID
- L’alias de rétrocompatibilité
django.template.loader.BaseLoader
est supprimé. - Les objets de gabarit Django renvoyés par
get_template()
etselect_template()
n’acceptent plus deContext
dans leur méthoderender()
. - Les API de réponse de gabarit forcent l’usage de
dict
et d’objets de gabarit dépendants du moteur au lieu de respectivementContext
et deTemplate
. - Le paramètre
current_app
a été supprimé des fonction et classes suivantes :django.shortcuts.render()
django.template.Context()
django.template.RequestContext()
django.template.response.TemplateResponse()
- Les paramètres
dictionary
etcontext_instance
ont été supprimés des fonctions suivantes :django.shortcuts.render()
django.shortcuts.render_to_response()
django.template.loader.render_to_string()
- Le paramètre
dirs
a été supprimé des fonctions suivantes :django.template.loader.get_template()
django.template.loader.select_template()
django.shortcuts.render()
django.shortcuts.render_to_response()
- Session verification is enabled regardless of whether or not
'django.contrib.auth.middleware.SessionAuthenticationMiddleware'
is inMIDDLEWARE_CLASSES
.SessionAuthenticationMiddleware
no longer has any purpose and can be removed fromMIDDLEWARE_CLASSES
. It’s kept as a stub until Django 2.0 as a courtesy for users who don’t read this note. - L’attribut privé
django.db.models.Field.related
est supprimé. - L’option
--list
de la commande d’administrationmigrate
est supprimée. - La balise de gabarit
ssi
est supprimée. - La prise en charge de l’opérateur de comparaison
=
est supprimée dans la balise de gabaritif
. - The backwards compatibility shims to allow
Storage.get_available_name()
andStorage.save()
to be defined without amax_length
argument are removed. - Support for the legacy
%(<foo>)s
syntax inModelFormMixin.success_url
is removed. GeoQuerySet
aggregate methodscollect()
,extent()
,extent3d()
,make_line()
, andunionagg()
are removed.- The ability to specify
ContentType.name
when creating a content type instance is removed. - Support for the old signature of
allow_migrate
is removed. - Support for the syntax of
{% cycle %}
that uses comma-separated arguments is removed. - The warning that
Signer
issued when given an invalid separator is now aValueError
.