Django 2.1 release notes
Welcome to Django 2.1!
These release notes cover the , as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 2.0 or earlier. We’ve that have reached the end of their deprecation cycle, and we’ve begun the deprecation process for some features.
如果你要更新现有的项目,请看 指南。
Django 2.1 supports Python 3.5, 3.6, and 3.7. Django 2.0 is the last version to support Python 3.4. We highly recommend and only officially support the latest release of each series.
A “view” permission is added to the model Meta.default_permissions
. The new permissions will be created automatically when running .
There are a couple of backwards incompatible considerations.
次要特性
ModelAdmin.search_fields
now accepts any lookup such asfield__exact
.- jQuery is upgraded from version 2.2.3 to 3.3.1.
- The new method allows customizing the deletion process of the “delete selected objects” action.
- You can now override the default admin site.
- The new attribute and
ModelAdmin.get_sortable_by()
method allow limiting the columns that can be sorted in the change list page. - The
admin_order_field
attribute for elements in may now be a query expression. - The
actions.html
,change_list_results.html
,date_hierarchy.html
,pagination.html
,prepopulated_fields_js.html
,search_form.html
, andsubmit_line.html
templates can now be overridden per app or per model (besides overridden globally). - The admin change list and change form object tools can now be with
change_list_object_tools.html
andchange_form_object_tools.html
templates. InlineModelAdmin.has_add_permission()
is now passed the parent object as the second positional argument,obj
.- Admin actions may now to limit their availability to certain users.
django.contrib.auth
- now gives a prompt to allow bypassing the
AUTH_PASSWORD_VALIDATORS
checks.
- The new
GEOSGeometry.buffer_with_style()
method is a version of that allows customizing the style of the buffer. OpenLayersWidget
is now based on OpenLayers 4.6.5 (previously 3.20.1).
- Added the
SESSION_COOKIE_SAMESITE
setting to set theSameSite
cookie flag on session cookies.
缓存
- The now uses a least-recently-used (LRU) culling strategy rather than a pseudo-random one.
- The new
touch()
method of the updates the timeout of cache keys.
CSRF
- Added the
CSRF_COOKIE_SAMESITE
setting to set theSameSite
cookie flag on CSRF cookies.
表单
- The widget for
ImageField
now renders with the HTML attributeaccept="image/*"
.
国际化
- Added the function.
- Untranslated strings for territorial language variants now use the translations of the generic language. For example, untranslated
pt_BR
strings usept
translations.
管理命令
- The new
inspectdb --include-views
option allows creating models for database views. - The class now uses a custom help formatter so that the standard options like
--verbosity
or--settings
appear last in the help output, giving a more prominent position to subclassed command’s options.
迁移
- Added support for serialization of
functools.partialmethod
objects. - To support frozen environments, migrations may be loaded from
.pyc
files.
模型
- Models can now use
__init_subclass__()
from PEP 487. - A
BinaryField
may now be set toeditable=True
if you wish to include it in model forms. - A number of new text database functions are added: ,
Left
, ,LTrim
, ,Repeat
, ,Right
, ,RTrim
, and . - The new
TruncWeek
function truncates andDateTimeField
to the Monday of a week. - Query expressions can now be negated using a minus sign.
- and
distinct(*fields)
now support using field transforms. - can now be
null=True
. This is encouraged instead ofNullBooleanField
, which will likely be deprecated in the future. - The new method displays the database’s execution plan of a queryset’s query.
QuerySet.raw()
now supports .
请求和响应
- Added
HttpRequest.get_full_path_info()
. - Added the
samesite
argument to to allow setting theSameSite
cookie flag. - The new
as_attachment
argument forFileResponse
sets theContent-Disposition
header to make the browser ask if the user wants to download the file.FileResponse
also tries to set theContent-Type
andContent-Length
headers where appropriate.
模板
- The new filter safely outputs a Python object as JSON, wrapped in a
<script>
tag, ready for use with JavaScript.
测试
- Added test
Client
support for 307 and 308 redirects. - The test now serializes a request data dictionary as JSON if
content_type='application/json'
. You can customize the JSON encoder with test client’sjson_encoder
parameter. - The new
SimpleTestCase.assertWarnsMessage()
method is a simpler version of .
数据库后端 API
本节介绍了第三方数据库后端可能需要的更改。
- To adhere to PEP 249, exceptions where a database doesn’t support a feature are changed from to
django.db.NotSupportedError
. - Renamed the
allow_sliced_subqueries
database feature flag toallow_sliced_subqueries_with_in
. DatabaseOperations.distinct_sql()
now requires an additionalparams
argument and returns a tuple of SQL and parameters instead of an SQL string.DatabaseFeatures.introspected_boolean_field_type
is changed from a method to a property.
- Support for SpatiaLite 4.0 is removed.
The end of upstream support for MySQL 5.5 is December 2018. Django 2.1 supports MySQL 5.6 and higher.
Dropped support for PostgreSQL 9.3
The end of upstream support for PostgreSQL 9.3 is September 2018. Django 2.1 supports PostgreSQL 9.4 and higher.
Removed BCryptPasswordHasher
from the default PASSWORD_HASHERS
setting
If you used bcrypt with Django 1.4 or 1.5 (before BCryptSHA256PasswordHasher
was added in Django 1.6), you might have some passwords that use the BCryptPasswordHasher
hasher.
If you want to continue to allow those passwords to be used, you’ll have to define the PASSWORD_HASHERS
setting (if you don’t already) and include 'django.contrib.auth.hashers.BCryptPasswordHasher'
.
Moved wrap_label
widget template context variable
To fix the lack of <label>
when using RadioSelect
and CheckboxSelectMultiple
with MultiWidget
, the wrap_label
context variable now appears as an attribute of each option. For example, in a custom input_option.html
template, change {% if wrap_label %}
to {% if widget.wrap_label %}
.
The cookies used for django.contrib.sessions
, django.contrib.messages
, and Django’s CSRF protection now set the SameSite
flag to Lax
by default. Browsers that respect this flag won’t send these cookies on cross-origin requests. If you rely on the old behavior, set the and/or CSRF_COOKIE_SAMESITE
setting to None
.
Considerations for the new model “view” permission
Custom admin forms need to take the view-only case into account
With the new “view” permission, existing custom admin forms may raise errors when a user doesn’t have the change permission because the form might access nonexistent fields. Fix this by overriding and checking if the user has the “change” permissions and returning the default form if not:
def get_form(self, request, obj=None, **kwargs):
if not self.has_change_permission(request, obj):
return super().get_form(request, obj, **kwargs)
return CustomForm
New default view permission could allow unwanted access to admin views
If you have a custom permission with a codename of the form view_<modelname>
, the new view permission handling in the admin will allow view access to the changelist and detail pages for those models. If this is unwanted, you must change your custom permission codename.
杂项
- The minimum supported version of
mysqlclient
is increased from 1.3.3 to 1.3.7. - Support for SQLite < 3.7.15 is removed.
- The date format of
Set-Cookie
‘sExpires
directive is changed to follow RFC 7231#section-7.1.1.1 instead of Netscape’s cookie standard. Hyphens present in dates likeTue, 25-Dec-2018 22:26:13 GMT
are removed. This change should be merely cosmetic except perhaps for antiquated browsers that don’t parse the new format. allowed_hosts
is now a required argument of private APIdjango.utils.http.is_safe_url()
.- The
multiple
attribute rendered by the widget now uses HTML5 boolean syntax rather than XHTML’smultiple="multiple"
. - HTML rendered by form widgets no longer includes a closing slash on void elements, e.g. . This is incompatible within XHTML, although some widgets already used aspects of HTML5 such as boolean attributes.
- The value of
SelectDateWidget
‘s empty options is changed from 0 to an empty string, which mainly may require some adjustments in tests that compare HTML. - and the
is_password_usable()
function no longer returnFalse
if the password isNone
or an empty string, or if the password uses a hasher that’s not in the setting. This undocumented behavior was a regression in Django 1.6 and prevented users with such passwords from requesting a password reset. Audit your code to confirm that your usage of these APIs don’t rely on the old behavior. - Since migrations are now loaded from
.pyc
files, you might need to delete them if you’re working in a mixed Python 2 and Python 3 environment. - Using
None
as aJSONField
lookup value now matches objects that have the specified key and a null value rather than objects that don’t have the key. - The admin CSS class
field-box
is renamed tofieldBox
to prevent conflicts with the class given to model fields named “box”. - Since the admin’s
actions.html
,change_list_results.html
,date_hierarchy.html
,pagination.html
,prepopulated_fields_js.html
,search_form.html
, andsubmit_line.html
templates can now be overridden per app or per model, you may need to rename existing templates with those names that were written for a different purpose. QuerySet.raw()
now caches its results like regular querysets. Useiterator()
if you don’t want caching.- The database router method is called in more cases. Improperly written routers may need to be updated accordingly.
- Translations are no longer deactivated before running management commands. If your custom command requires translations to be deactivated (for example, to insert untranslated content into the database), use the new @no_translations decorator.
- Management commands no longer allow the abbreviated forms of the
--settings
and--pythonpath
arguments. - The private
django.db.models.sql.constants.QUERY_TERMS
constant is removed. The andget_lookups()
methods of the may be suitable alternatives. Compared to theQUERY_TERMS
constant, they allow your code to also account for any custom lookups that have been registered. - Compatibility with
py-bcrypt
is removed as it’s unmaintained. Use bcrypt instead.
杂项
- The
ForceRHR
GIS function is deprecated in favor of the new function. django.utils.http.cookie_date()
is deprecated in favor ofhttp_date()
, which follows the format of the latest RFC.{% load staticfiles %}
and{% load admin_static %}
are deprecated in favor of{% load static %}
, which works the same.django.contrib.staticfiles.templatetags.static()
is deprecated in favor ofdjango.templatetags.static.static()
.- Support for methods that don’t accept
obj
as the second positional argument will be removed in Django 3.0.
contrib.auth.views.login()
,logout()
,password_change()
,password_change_done()
,password_reset()
,password_reset_done()
,password_reset_confirm()
, andpassword_reset_complete()
are removed.- The
extra_context
parameter ofcontrib.auth.views.logout_then_login()
is removed. django.test.runner.setup_databases()
is removed.django.utils.translation.string_concat()
is removed.django.core.cache.backends.memcached.PyLibMCCache
no longer supports passingpylibmc
behavior settings as top-level attributes ofOPTIONS
.- The
host
parameter ofdjango.utils.http.is_safe_url()
is removed. - Silencing of exceptions raised while rendering the
{% include %}
template tag is removed. DatabaseIntrospection.get_indexes()
is removed.- The
authenticate()
method of authentication backends requiresrequest
as the first positional argument. - The
django.db.models.permalink()
decorator is removed. - The
USE_ETAGS
setting is removed.CommonMiddleware
anddjango.utils.cache.patch_response_headers()
no longer set ETags. - The
Model._meta.has_auto_field
attribute is removed. - Support for
Widget.render()
methods without the argument is removed.