Django 2.2 版本发行说明
April 1, 2019
Welcome to Django 2.2!
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 2.1 or earlier. We’ve begun the deprecation process for some features.
如果你要更新现有的项目,请看 How to upgrade Django to a newer version 指南。
Django 2.2 is designated as a long-term support release. It will receive security updates for at least three years after its release. Support for the previous LTS, Django 1.11, will end in April 2020.
Python 兼容性
Django 2.2 supports Python 3.5, 3.6, 3.7, 3.8 (as of 2.2.8), and 3.9 (as of 2.2.17). We highly recommend and only officially support the latest release of each series.
What’s new in Django 2.2
Constraints
The new CheckConstraint and UniqueConstraint classes enable adding custom database constraints. Constraints are added to models using the Meta.constraints option.
次要特性
django.contrib.admin
- Added a CSS class to the column headers of TabularInline.
django.contrib.auth
- The
HttpRequest
is now passed as the first positional argument to RemoteUserBackend.configure_user(), if it accepts it.
django.contrib.gis
- Added Oracle support for the Envelope function.
- Added SpatiaLite support for the coveredby and covers lookups.
django.contrib.postgres
- The new
ordering
argument for ArrayAgg and StringAgg determines the ordering of the aggregated elements. - The new BTreeIndex, HashIndex and SpGistIndex classes allow creating
B-Tree
,hash
, andSP-GiST
indexes in the database. - BrinIndex now has the
autosummarize
parameter. - The new
search_type
parameter of SearchQuery allows searching for a phrase or raw expression.
django.contrib.staticfiles
- Added path matching to the collectstatic —ignore option so that patterns like
/vendor/*.js
can be used.
数据库后端
- Added result streaming for QuerySet.iterator() on SQLite.
通用视图
- The new View.setup hook initializes view attributes before calling dispatch(). It allows mixins to set up instance attributes for reuse in child classes.
国际化
- Added support and translations for the Armenian language.
管理命令
- The new --force-color option forces colorization of the command output.
- inspectdb now creates models for foreign tables on PostgreSQL.
- inspectdb —include-views now creates models for materialized views on Oracle and PostgreSQL.
- The new inspectdb —include-partitions option allows creating models for partition tables on PostgreSQL. In older versions, models are created child tables instead the parent.
- inspectdb now introspects DurationField for Oracle and PostgreSQL, and AutoField for SQLite.
- On Oracle, dbshell is wrapped with
rlwrap
, if available.rlwrap
provides a command history and editing of keyboard input. - The new makemigrations —no-header option avoids writing header comments in generated migration file(s). This option is also available for squashmigrations.
- runserver can now use Watchman to improve the performance of watching a large number of files for changes.
迁移
- The new migrate —plan option prints the list of migration operations that will be performed.
NoneType
can now be serialized in migrations.- You can now register custom serializers for migrations.
模型
- Added support for PostgreSQL operator classes (Index.opclasses).
- Added support for partial indexes (Index.condition).
- Added the NullIf and Reverse database functions, as well as many math database functions.
- Setting the new
ignore_conflicts
parameter of QuerySet.bulk_create() toTrue
tells the database to ignore failure to insert rows that fail uniqueness constraints or other checks. - The new ExtractIsoYear function extracts ISO-8601 week-numbering years from DateField and DateTimeField, and the new iso_year lookup allows querying by an ISO-8601 week-numbering year.
- The new QuerySet.bulk_update() method allows efficiently updating specific fields on multiple model instances.
- Django no longer always starts a transaction when a single query is being performed, such as
Model.save()
,QuerySet.update()
, andModel.delete()
. This improves the performance of autocommit by reducing the number of database round trips. - Added SQLite support for the StdDev and Variance functions.
- The handling of
DISTINCT
aggregation is added to the Aggregate class. Adding allow_distinct = True as a class attribute onAggregate
subclasses allows adistinct
keyword argument to be specified on initialization to ensure that the aggregate function is only called for each distinct value ofexpressions
. - The RelatedManager.add(), create(), remove(), set(),
get_or_create()
, andupdate_or_create()
methods are now allowed on many-to-many relationships with intermediate models. The newthrough_defaults
argument is used to specify values for new intermediate model instance(s).
请求和响应
- Added HttpRequest.headers to allow simple access to a request’s headers.
序列化
- You can now deserialize data using natural keys containing forward references by passing
handle_forward_references=True
toserializers.deserialize()
. Additionally, loaddata handles forward references automatically.
测试
- The new SimpleTestCase.assertURLEqual() assertion checks for a given URL, ignoring the ordering of the query string. assertRedirects() uses the new assertion.
- The test Client now supports automatic JSON serialization of list and tuple
data
whencontent_type='application/json'
. - The new ORACLE_MANAGED_FILES test database setting allows using Oracle Managed Files (OMF) tablespaces.
- Deferrable database constraints are now checked at the end of each TestCase test on SQLite 3.20+, just like on other backends that support deferrable constraints. These checks aren’t implemented for older versions of SQLite because they would require expensive table introspection there.
- DiscoverRunner now skips the setup of databases not referenced by tests.
URLs
- The new ResolverMatch.route attribute stores the route of the matching URL pattern.
验证器
- MaxValueValidator, MinValueValidator, MinLengthValidator, and MaxLengthValidator now accept a callable
limit_value
.
Backwards incompatible changes in 2.2
数据库后端 API
本节介绍了第三方数据库后端可能需要的更改。
- Third-party database backends must implement support for table check constraints or set
DatabaseFeatures.supports_table_check_constraints
toFalse
. - Third party database backends must implement support for ignoring constraints or uniqueness errors while inserting or set
DatabaseFeatures.supports_ignore_conflicts
toFalse
. - Third party database backends must implement introspection for
DurationField
or setDatabaseFeatures.can_introspect_duration_field
toFalse
. DatabaseFeatures.uses_savepoints
now defaults toTrue
.- Third party database backends must implement support for partial indexes or set
DatabaseFeatures.supports_partial_indexes
toFalse
. DatabaseIntrospection.table_name_converter()
andcolumn_name_converter()
are removed. Third party database backends may need to instead implementDatabaseIntrospection.identifier_converter()
. In that case, the constraint names thatDatabaseIntrospection.get_constraints()
returns must be normalized byidentifier_converter()
.- SQL generation for indexes is moved from Index to
SchemaEditor
and theseSchemaEditor
methods are added:_create_primary_key_sql()
and_delete_primary_key_sql()
_delete_index_sql()
(to pair with_create_index_sql()
)_delete_unique_sql
(to pair with_create_unique_sql()
)_delete_fk_sql()
(to pair with_create_fk_sql()
)_create_check_sql()
and_delete_check_sql()
- The third argument of
DatabaseWrapper.__init__()
,allow_thread_sharing
, is removed.
Admin actions are no longer collected from base ModelAdmin
classes
For example, in older versions of Django:
from django.contrib import admin
class BaseAdmin(admin.ModelAdmin):
actions = ['a']
class SubAdmin(BaseAdmin):
actions = ['b']
SubAdmin
would have actions 'a'
and 'b'
.
Now actions
follows standard Python inheritance. To get the same result as before:
class SubAdmin(BaseAdmin):
actions = BaseAdmin.actions + ['b']
django.contrib.gis
- Support for GDAL 1.9 and 1.10 is dropped.
TransactionTestCase
serialized data loading
Initial data migrations are now loaded in TransactionTestCase at the end of the test, after the database flush. In older versions, this data was loaded at the beginning of the test, but this prevents the test —keepdb option from working properly (the database was empty at the end of the whole test suite). This change shouldn’t have an impact on your tests unless you’ve customized TransactionTestCase‘s internals.
sqlparse
is required dependency
To simplify a few parts of Django’s database handling, sqlparse 0.2.2+ is now a required dependency. It’s automatically installed along with Django.
cached_property
aliases
In usage like:
from django.utils.functional import cached_property
class A:
@cached_property
def base(self):
return ...
alias = base
alias
is not cached. Where the problem can be detected (Python 3.6 and later), such usage now raises TypeError: Cannot assign the same cached_property to two different names ('base' and 'alias').
Use this instead:
import operator
class A:
...
alias = property(operator.attrgetter('base'))
Permissions for proxy models
Permissions for proxy models are now created using the content type of the proxy model rather than the content type of the concrete model. A migration will update existing permissions when you run migrate.
In the admin, the change is transparent for proxy models having the same app_label
as their concrete model. However, in older versions, users with permissions for a proxy model with a different app_label
than its concrete model couldn’t access the model in the admin. That’s now fixed, but you might want to audit the permissions assignments for such proxy models ([add|view|change|delete]_myproxy
) prior to upgrading to ensure the new access is appropriate.
Finally, proxy model permission strings must be updated to use their own app_label
. For example, for app.MyProxyModel
inheriting from other_app.ConcreteModel
, update user.has_perm('other_app.add_myproxymodel')
to user.has_perm('app.add_myproxymodel')
.
Merging of form Media
assets
Form Media
assets are now merged using a topological sort algorithm, as the old pairwise merging algorithm is insufficient for some cases. CSS and JavaScript files which don’t include their dependencies may now be sorted incorrectly (where the old algorithm produced results correctly by coincidence).
Audit all Media
classes for any missing dependencies. For example, widgets depending on django.jQuery
must specify js=['admin/js/jquery.init.js', ...]
when declaring form media assets.
杂项
To improve readability, the
UUIDField
form field now displays values with dashes, e.g.550e8400-e29b-41d4-a716-446655440000
instead of550e8400e29b41d4a716446655440000
.On SQLite,
PositiveIntegerField
andPositiveSmallIntegerField
now include a check constraint to prevent negative values in the database. If you have existing invalid data and run a migration that recreates a table, you’ll seeCHECK constraint failed
.For consistency with WSGI servers, the test client now sets the
Content-Length
header to a string rather than an integer.The return value of django.utils.text.slugify() is no longer marked as HTML safe.
The default truncation character used by the urlizetrunc, truncatechars, truncatechars_html, truncatewords, and truncatewords_html template filters is now the real ellipsis character (
…
) instead of 3 dots. You may have to adapt some test output comparisons.Support for bytestring paths in the template filesystem loader is removed.
django.utils.http.urlsafe_base64_encode() now returns a string instead of a bytestring, and django.utils.http.urlsafe_base64_decode() may no longer be passed a bytestring.
Support for
cx_Oracle
< 6.0 is removed.The minimum supported version of
mysqlclient
is increased from 1.3.7 to 1.3.13.The minimum supported version of SQLite is increased from 3.7.15 to 3.8.3.
In an attempt to provide more semantic query data,
NullBooleanSelect
now renders<option>
values ofunknown
,true
, andfalse
instead of1
,2
, and3
. For backwards compatibility, the old values are still accepted as data.Group.name
max_length
is increased from 80 to 150 characters.Tests that violate deferrable database constraints now error when run on SQLite 3.20+, just like on other backends that support such constraints.
To catch usage mistakes, the test Client and django.utils.http.urlencode() now raise
TypeError
ifNone
is passed as a value to encode becauseNone
can’t be encoded in GET and POST data. Either pass an empty string or omit the value.The ping_google management command now defaults to
https
instead ofhttp
for the sitemap’s URL. If your site uses http, use the new ping_google —sitemap-uses-http option. If you use the ping_google() function, set the newsitemap_uses_https
argument toFalse
.runserver no longer supports
pyinotify
(replaced by Watchman).The Avg, StdDev, and Variance aggregate functions now return a
Decimal
instead of afloat
when the input isDecimal
.Tests will fail on SQLite if apps without migrations have relations to apps with migrations. This has been a documented restriction since migrations were added in Django 1.7, but it fails more reliably now. You’ll see tests failing with errors like
no such table: <app_label>_<model>
. This was observed with several third-party apps that had models in tests without migrations. You must add migrations for such models.Providing an integer in the
key
argument of the cache.delete() or cache.get() now raises ValueError.Plural equations for some languages are changed, because the latest versions from Transifex are incorporated.
注解
The ability to handle
.po
files containing different plural equations for the same language was added in Django 2.2.12.
在 2.2 中被废弃的功能
Model Meta.ordering
will no longer affect GROUP BY
queries
A model’s Meta.ordering
affecting GROUP BY
queries (such as .annotate().values()
) is a common source of confusion. Such queries now issue a deprecation warning with the advice to add an order_by()
to retain the current query. Meta.ordering
will be ignored in such queries starting in Django 3.1.
杂项
django.utils.timezone.FixedOffset
is deprecated in favor of datetime.timezone.- The undocumented
QuerySetPaginator
alias ofdjango.core.paginator.Paginator
is deprecated. - The
FloatRangeField
model and form fields indjango.contrib.postgres
are deprecated in favor of a new name,DecimalRangeField
, to match the underlyingnumrange
data type used in the database. - The
FILE_CHARSET
setting is deprecated. Starting with Django 3.1, files read from disk must be UTF-8 encoded. django.contrib.staticfiles.storage.CachedStaticFilesStorage
is deprecated due to the intractable problems that it has. Use ManifestStaticFilesStorage or a third-party cloud storage instead.- RemoteUserBackend.configure_user() is now passed
request
as the first positional argument, if it accepts it. Support for overrides that don’t accept it will be removed in Django 3.1. - The
SimpleTestCase.allow_database_queries
,TransactionTestCase.multi_db
, andTestCase.multi_db
attributes are deprecated in favor of SimpleTestCase.databases, TransactionTestCase.databases, and TestCase.databases. These new attributes allow databases dependencies to be declared in order to prevent unexpected queries against non-default databases to leak state between tests. The previous behavior ofallow_database_queries=True
andmulti_db=True
can be achieved by settingdatabases='__all__'
.