From 6b9b2af7352908d40ca4d31bdb1b80c013cab29a Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Mon, 4 May 2020 11:44:22 +0200 Subject: [PATCH 0001/1251] Bumped version; master is now 3.2 pre-alpha. --- django/__init__.py | 2 +- docs/conf.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/django/__init__.py b/django/__init__.py index 2da16633d84f..c6bda275109a 100644 --- a/django/__init__.py +++ b/django/__init__.py @@ -1,6 +1,6 @@ from django.utils.version import get_version -VERSION = (3, 1, 0, 'alpha', 0) +VERSION = (3, 2, 0, 'alpha', 0) __version__ = get_version(VERSION) diff --git a/docs/conf.py b/docs/conf.py index 316408dbf1b0..4970e754c78b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -83,7 +83,7 @@ # built documents. # # The short X.Y version. -version = '3.1' +version = '3.2' # The full version, including alpha/beta/rc tags. try: from django import VERSION, get_version @@ -99,7 +99,7 @@ def django_release(): release = django_release() # The "development version" of Django -django_next_version = '3.1' +django_next_version = '3.2' extlinks = { 'commit': ('https://github.com/django/django/commit/%s', ''), From 3b94f12462d262a812930cf25efe8d8eb07c5c83 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Mon, 4 May 2020 11:46:46 +0200 Subject: [PATCH 0002/1251] Added stub release notes for 3.2. --- docs/faq/install.txt | 5 +- docs/releases/3.2.txt | 239 ++++++++++++++++++++++++++++++++++++++++ docs/releases/index.txt | 7 ++ 3 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 docs/releases/3.2.txt diff --git a/docs/faq/install.txt b/docs/faq/install.txt index 2cbbb83b7f28..dfc4dc5d7e26 100644 --- a/docs/faq/install.txt +++ b/docs/faq/install.txt @@ -50,11 +50,8 @@ What Python version can I use with Django? ============== =============== Django version Python versions ============== =============== -1.11 2.7, 3.4, 3.5, 3.6, 3.7 (added in 1.11.17) -2.0 3.4, 3.5, 3.6, 3.7 -2.1 3.5, 3.6, 3.7 2.2 3.5, 3.6, 3.7, 3.8 (added in 2.2.8) -3.0, 3.1 3.6, 3.7, 3.8 +3.0, 3.1, 3.2 3.6, 3.7, 3.8 ============== =============== For each version of Python, only the latest micro release (A.B.C) is officially diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt new file mode 100644 index 000000000000..41e820434570 --- /dev/null +++ b/docs/releases/3.2.txt @@ -0,0 +1,239 @@ +============================================ +Django 3.2 release notes - UNDER DEVELOPMENT +============================================ + +*Expected April 2021* + +Welcome to Django 3.2! + +These release notes cover the :ref:`new features `, as well as +some :ref:`backwards incompatible changes ` you'll +want to be aware of when upgrading from Django 3.1 or earlier. We've +:ref:`begun the deprecation process for some features +`. + +See the :doc:`/howto/upgrade-version` guide if you're updating an existing +project. + +Django 3.2 is designated as a :term:`long-term support release +`. It will receive security updates for at least +three years after its release. Support for the previous LTS, Django 2.2, will +end in April 2022. + +Python compatibility +==================== + +Django 3.2 supports Python 3.6, 3.7, and 3.8. We **highly recommend** and only +officially support the latest release of each series. + +.. _whats-new-3.2: + +What's new in Django 3.2 +======================== + +Minor features +-------------- + +:mod:`django.contrib.admin` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.admindocs` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.auth` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.contenttypes` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.gis` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.messages` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.postgres` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.redirects` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.sessions` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.sitemaps` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.sites` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.staticfiles` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.syndication` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +Cache +~~~~~ + +* ... + +CSRF +~~~~ + +* ... + +Email +~~~~~ + +* ... + +Error Reporting +~~~~~~~~~~~~~~~ + +* ... + +File Storage +~~~~~~~~~~~~ + +* ... + +File Uploads +~~~~~~~~~~~~ + +* ... + + +Forms +~~~~~ + +* ... + +Generic Views +~~~~~~~~~~~~~ + +* ... + +Internationalization +~~~~~~~~~~~~~~~~~~~~ + +* ... + +Logging +~~~~~~~ + +* ... + +Management Commands +~~~~~~~~~~~~~~~~~~~ + +* ... + +Migrations +~~~~~~~~~~ + +* ... + +Models +~~~~~~ + +* ... + +Requests and Responses +~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +Security +~~~~~~~~ + +* ... + +Serialization +~~~~~~~~~~~~~ + +* ... + +Signals +~~~~~~~ + +* ... + +Templates +~~~~~~~~~ + +* ... + +Tests +~~~~~ + +* ... + +URLs +~~~~ + +* ... + +Utilities +~~~~~~~~~ + +* ... + +Validators +~~~~~~~~~~ + +* ... + +.. _backwards-incompatible-3.2: + +Backwards incompatible changes in 3.2 +===================================== + +Database backend API +-------------------- + +This section describes changes that may be needed in third-party database +backends. + +* ... + +Miscellaneous +------------- + +* ... + +.. _deprecated-features-3.2: + +Features deprecated in 3.2 +========================== + +Miscellaneous +------------- + +* ... diff --git a/docs/releases/index.txt b/docs/releases/index.txt index 710f09b54a7f..4e337dcf7d60 100644 --- a/docs/releases/index.txt +++ b/docs/releases/index.txt @@ -20,6 +20,13 @@ versions of the documentation contain the release notes for any later releases. .. _development_release_notes: +3.2 release +----------- +.. toctree:: + :maxdepth: 1 + + 3.2 + 3.1 release ----------- .. toctree:: From 4c5236ef93db714b63eedcc5a162631a6ca1def9 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Mon, 4 May 2020 12:29:31 +0200 Subject: [PATCH 0003/1251] Removed versionadded/changed annotations for 3.0. --- docs/howto/custom-file-storage.txt | 2 - docs/ref/clickjacking.txt | 5 --- docs/ref/contrib/admin/index.txt | 6 --- docs/ref/contrib/auth.txt | 12 ------ docs/ref/contrib/gis/db-api.txt | 4 -- docs/ref/contrib/gis/functions.txt | 2 - docs/ref/contrib/gis/geoip2.txt | 8 ---- docs/ref/contrib/gis/geoquerysets.txt | 44 --------------------- docs/ref/contrib/humanize.txt | 5 --- docs/ref/contrib/postgres/constraints.txt | 2 - docs/ref/contrib/postgres/fields.txt | 4 -- docs/ref/contrib/postgres/operations.txt | 2 - docs/ref/contrib/syndication.txt | 5 --- docs/ref/databases.txt | 2 - docs/ref/django-admin.txt | 22 ----------- docs/ref/exceptions.txt | 4 -- docs/ref/files/storage.txt | 2 - docs/ref/middleware.txt | 2 - docs/ref/models/conditional-expressions.txt | 6 --- docs/ref/models/constraints.txt | 8 ---- docs/ref/models/database-functions.txt | 10 ----- docs/ref/models/expressions.txt | 11 ------ docs/ref/models/fields.txt | 21 ---------- docs/ref/models/indexes.txt | 4 -- docs/ref/models/instances.txt | 6 --- docs/ref/models/querysets.txt | 8 ---- docs/ref/request-response.txt | 12 ------ docs/ref/settings.txt | 20 ---------- docs/ref/utils.txt | 17 +------- docs/topics/async.txt | 2 - docs/topics/auth/customizing.txt | 10 ----- docs/topics/auth/default.txt | 4 -- docs/topics/forms/formsets.txt | 4 -- docs/topics/http/decorators.txt | 4 -- docs/topics/http/sessions.txt | 2 - docs/topics/http/urls.txt | 5 --- docs/topics/i18n/translation.txt | 4 -- docs/topics/logging.txt | 4 -- docs/topics/testing/tools.txt | 6 --- 39 files changed, 2 insertions(+), 299 deletions(-) diff --git a/docs/howto/custom-file-storage.txt b/docs/howto/custom-file-storage.txt index 33b8223b60c9..7fd71ffef070 100644 --- a/docs/howto/custom-file-storage.txt +++ b/docs/howto/custom-file-storage.txt @@ -99,8 +99,6 @@ and underscores from the original filename, removing everything else. .. method:: get_alternative_name(file_root, file_ext) -.. versionadded:: 3.0 - Returns an alternative filename based on the ``file_root`` and ``file_ext`` parameters. By default, an underscore plus a random 7 character alphanumeric string is appended to the filename before the extension. diff --git a/docs/ref/clickjacking.txt b/docs/ref/clickjacking.txt index d7eec879238a..9d7c5cb0c3d9 100644 --- a/docs/ref/clickjacking.txt +++ b/docs/ref/clickjacking.txt @@ -72,11 +72,6 @@ this header instead, set the :setting:`X_FRAME_OPTIONS` setting:: X_FRAME_OPTIONS = 'SAMEORIGIN' -.. versionchanged:: 3.0 - - The default value of the :setting:`X_FRAME_OPTIONS` setting was changed - from ``SAMEORIGIN`` to ``DENY``. - When using the middleware there may be some views where you do **not** want the ``X-Frame-Options`` header set. For those cases, you can use a view decorator that tells the middleware not to set the header:: diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index e5ec730c820f..1dd7812c419d 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -1649,8 +1649,6 @@ templates used by the :class:`ModelAdmin` views: .. method:: ModelAdmin.get_inlines(request, obj) - .. versionadded:: 3.0 - The ``get_inlines`` method is given the ``HttpRequest`` and the ``obj`` being edited (or ``None`` on an add form) and is expected to return an iterable of inlines. You can override this method to dynamically add @@ -2151,10 +2149,6 @@ To avoid conflicts with user-supplied scripts or libraries, Django's jQuery in your own admin JavaScript without including a second copy, you can use the ``django.jQuery`` object on changelist and add/edit views. -.. versionchanged:: 3.0 - - jQuery was upgraded from 3.3.1 to 3.4.1. - .. versionchanged:: 3.1 jQuery was upgraded from 3.4.1 to 3.5.1. diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt index 4d50fd123aa3..de2a2321baa2 100644 --- a/docs/ref/contrib/auth.txt +++ b/docs/ref/contrib/auth.txt @@ -194,8 +194,6 @@ Methods .. method:: get_user_permissions(obj=None) - .. versionadded:: 3.0 - Returns a set of permission strings that the user has directly. If ``obj`` is passed in, only returns the user permissions for this @@ -288,14 +286,8 @@ Manager methods Same as :meth:`create_user`, but sets :attr:`~models.User.is_staff` and :attr:`~models.User.is_superuser` to ``True``. - .. versionchanged:: 3.0 - - The ``email`` and ``password`` parameters were made optional. - .. method:: with_perm(perm, is_active=True, include_superusers=True, backend=None, obj=None) - .. versionadded:: 3.0 - Returns users that have the given permission ``perm`` either in the ``"."`` format or as a :class:`~django.contrib.auth.models.Permission` instance. Returns an @@ -499,8 +491,6 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. class:: BaseBackend - .. versionadded:: 3.0 - A base class that provides default implementations for all required methods. By default, it will reject any user and provide no permissions. @@ -603,8 +593,6 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. method:: with_perm(perm, is_active=True, include_superusers=True, obj=None) - .. versionadded:: 3.0 - Returns all active users who have the permission ``perm`` either in the form of ``"."`` or a :class:`~django.contrib.auth.models.Permission` instance. Returns an diff --git a/docs/ref/contrib/gis/db-api.txt b/docs/ref/contrib/gis/db-api.txt index 03c9c5a72462..928d12aa420a 100644 --- a/docs/ref/contrib/gis/db-api.txt +++ b/docs/ref/contrib/gis/db-api.txt @@ -28,10 +28,6 @@ not conform to the OGC standard. Django supports spatial functions operating on real geometries available in modern MySQL versions. However, the spatial functions are not as rich as other backends like PostGIS. -.. versionchanged:: 3.0 - - Support for spatial functions operating on real geometries was added. - .. warning:: True spatial indexes (R-trees) are only supported with diff --git a/docs/ref/contrib/gis/functions.txt b/docs/ref/contrib/gis/functions.txt index 6f10fc4ac1d1..351429b49e6f 100644 --- a/docs/ref/contrib/gis/functions.txt +++ b/docs/ref/contrib/gis/functions.txt @@ -361,8 +361,6 @@ __ https://en.wikipedia.org/wiki/Geohash .. class:: GeometryDistance(expr1, expr2, **extra) -.. versionadded:: 3.0 - *Availability*: `PostGIS `__ Accepts two geographic fields or expressions and returns the distance between diff --git a/docs/ref/contrib/gis/geoip2.txt b/docs/ref/contrib/gis/geoip2.txt index 83593f0ae17d..5d0d31cfd88e 100644 --- a/docs/ref/contrib/gis/geoip2.txt +++ b/docs/ref/contrib/gis/geoip2.txt @@ -86,10 +86,6 @@ Keyword Arguments Description the :setting:`GEOIP_CITY` setting. =================== ======================================================= -.. versionchanged:: 3.0 - - Support for :class:`pathlib.Path` ``path`` was added. - Methods ======= @@ -159,10 +155,6 @@ A string or :class:`pathlib.Path` specifying the directory where the GeoIP data files are located. This setting is *required* unless manually specified with ``path`` keyword when initializing the :class:`GeoIP2` object. -.. versionchanged:: 3.0 - - Support for :class:`pathlib.Path` was added. - .. setting:: GEOIP_COUNTRY ``GEOIP_COUNTRY`` diff --git a/docs/ref/contrib/gis/geoquerysets.txt b/docs/ref/contrib/gis/geoquerysets.txt index beda7b538e94..dfda2fa3b7cf 100644 --- a/docs/ref/contrib/gis/geoquerysets.txt +++ b/docs/ref/contrib/gis/geoquerysets.txt @@ -156,11 +156,6 @@ MySQL ``ST_Contains(poly, geom)`` SpatiaLite ``Contains(poly, geom)`` ========== ============================ -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBRContains`` and operates only on bounding - boxes. - .. fieldlookup:: contains_properly ``contains_properly`` @@ -251,10 +246,6 @@ MySQL ``ST_Crosses(poly, geom)`` SpatiaLite ``Crosses(poly, geom)`` ========== ========================== -.. versionchanged:: 3.0 - - MySQL support was added. - .. fieldlookup:: disjoint ``disjoint`` @@ -279,11 +270,6 @@ MySQL ``ST_Disjoint(poly, geom)`` SpatiaLite ``Disjoint(poly, geom)`` ========== ================================================= -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBRDisjoint`` and operates only on bounding - boxes. - .. fieldlookup:: equals ``equals`` @@ -308,11 +294,6 @@ MySQL ``ST_Equals(poly, geom)`` SpatiaLite ``Equals(poly, geom)`` ========== ================================================= -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBREquals`` and operates only on bounding - boxes. - .. fieldlookup:: exact :noindex: .. fieldlookup:: same_as @@ -341,11 +322,6 @@ MySQL ``ST_Equals(poly, geom)`` SpatiaLite ``Equals(poly, geom)`` ========== ================================================= -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBREquals`` and operates only on bounding - boxes. - .. fieldlookup:: intersects ``intersects`` @@ -370,11 +346,6 @@ MySQL ``ST_Intersects(poly, geom)`` SpatiaLite ``Intersects(poly, geom)`` ========== ================================================= -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBRIntersects`` and operates only on - bounding boxes. - .. fieldlookup:: isvalid ``isvalid`` @@ -416,11 +387,6 @@ MySQL ``ST_Overlaps(poly, geom)`` SpatiaLite ``Overlaps(poly, geom)`` ========== ============================ -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBROverlaps`` and operates only on bounding - boxes. - .. fieldlookup:: relate ``relate`` @@ -521,11 +487,6 @@ Oracle ``SDO_TOUCH(poly, geom)`` SpatiaLite ``Touches(poly, geom)`` ========== ========================== -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBRTouches`` and operates only on bounding - boxes. - .. fieldlookup:: within ``within`` @@ -550,11 +511,6 @@ Oracle ``SDO_INSIDE(poly, geom)`` SpatiaLite ``Within(poly, geom)`` ========== ========================== -.. versionchanged:: 3.0 - - In older versions, MySQL uses ``MBRWithin`` and operates only on bounding - boxes. - .. fieldlookup:: left ``left`` diff --git a/docs/ref/contrib/humanize.txt b/docs/ref/contrib/humanize.txt index 8914ef8de77e..00718582f505 100644 --- a/docs/ref/contrib/humanize.txt +++ b/docs/ref/contrib/humanize.txt @@ -78,11 +78,6 @@ e.g. with the ``'de'`` language: * ``1200000000`` becomes ``'1,2 Milliarden'``. * ``-1200000000`` becomes ``'-1,2 Milliarden'``. -.. versionchanged:: 3.0 - - All numeric values are now translated as plural, except ``1.0`` which is - translated as a singular phrase. This may be incorrect for some languages. - .. versionchanged:: 3.1 Support for negative integers was added. diff --git a/docs/ref/contrib/postgres/constraints.txt b/docs/ref/contrib/postgres/constraints.txt index 8b82221ebdfa..f90667c39453 100644 --- a/docs/ref/contrib/postgres/constraints.txt +++ b/docs/ref/contrib/postgres/constraints.txt @@ -12,8 +12,6 @@ PostgreSQL supports additional data integrity constraints available from the ``ExclusionConstraint`` ======================= -.. versionadded:: 3.0 - .. class:: ExclusionConstraint(*, name, expressions, index_type=None, condition=None, deferrable=None) Creates an exclusion constraint in the database. Internally, PostgreSQL diff --git a/docs/ref/contrib/postgres/fields.txt b/docs/ref/contrib/postgres/fields.txt index aeacc72e7c97..b5df10320634 100644 --- a/docs/ref/contrib/postgres/fields.txt +++ b/docs/ref/contrib/postgres/fields.txt @@ -889,8 +889,6 @@ types. Range operators --------------- -.. versionadded:: 3.0 - .. class:: RangeOperators PostgreSQL provides a set of SQL operators that can be used together with the @@ -917,8 +915,6 @@ corresponding lookups. RangeBoundary() expressions --------------------------- -.. versionadded:: 3.0 - .. class:: RangeBoundary(inclusive_lower=True, inclusive_upper=False) .. attribute:: inclusive_lower diff --git a/docs/ref/contrib/postgres/operations.txt b/docs/ref/contrib/postgres/operations.txt index 620e5db8b71a..b7dc0726e7bb 100644 --- a/docs/ref/contrib/postgres/operations.txt +++ b/docs/ref/contrib/postgres/operations.txt @@ -111,8 +111,6 @@ run the query ``CREATE EXTENSION IF NOT EXISTS hstore;``. Index concurrent operations =========================== -.. versionadded:: 3.0 - PostgreSQL supports the ``CONCURRENTLY`` option to ``CREATE INDEX`` and ``DROP INDEX`` statements to add and remove indexes without locking out writes. This option is useful for adding or removing an index in a live production diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt index ddafae3c0dd2..13aa944e8a05 100644 --- a/docs/ref/contrib/syndication.txt +++ b/docs/ref/contrib/syndication.txt @@ -310,11 +310,6 @@ appropriate ```` tag (RSS 2.0) or ``xml:lang`` attribute (Atom). By default, this is :func:`django.utils.translation.get_language()`. You can change it by setting the ``language`` class attribute. -.. versionchanged:: 3.0 - - The ``language`` class attribute was added. In older versions, the behavior - is the same as ``language = settings.LANGUAGE_CODE``. - URLs ---- diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index a16f525d96fa..ef384f14e922 100644 --- a/docs/ref/databases.txt +++ b/docs/ref/databases.txt @@ -287,8 +287,6 @@ non-durable `_. MariaDB notes ============= -.. versionadded:: 3.0 - Django supports MariaDB 10.2 and higher. To use MariaDB, use the MySQL backend, which is shared between the two. See the diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index 35d6c04b30f5..f48307fe2235 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -175,8 +175,6 @@ Example usage:: .. django-admin-option:: --ignore PATTERN, -i PATTERN -.. versionadded:: 3.0 - Ignores directories matching the given :mod:`glob`-style pattern. Use multiple times to ignore more. @@ -1131,10 +1129,6 @@ under them. This is the default output format. -.. versionchanged:: 3.0 - - Output of the applied datetimes at verbosity 2 and above was added. - .. django-admin-option:: --plan, -p Shows the migration plan Django will follow to apply migrations. Like @@ -1276,11 +1270,6 @@ zip files, you can use a URL like:: django-admin startapp --template=https://github.com/githubuser/django-app-template/archive/master.zip myapp -.. versionchanged:: 3.0 - - Support for XZ archives (``.tar.xz``, ``.txz``) and LZMA archives - (``.tar.lzma``, ``.tlz``) was added. - .. django-admin-option:: --extension EXTENSIONS, -e EXTENSIONS Specifies which file extensions in the app template should be rendered with the @@ -1490,8 +1479,6 @@ May be specified multiple times and combined with :option:`test --tag`. .. django-admin-option:: -k TEST_NAME_PATTERNS -.. versionadded:: 3.0 - Runs test methods and classes matching test name patterns, in the same way as :option:`unittest's -k option`. Can be specified multiple times. @@ -1501,8 +1488,6 @@ Runs test methods and classes matching test name patterns, in the same way as .. django-admin-option:: --pdb -.. versionadded:: 3.0 - Spawns a ``pdb`` debugger at each test error or failure. If you have it installed, ``ipdb`` is used instead. @@ -1635,11 +1620,6 @@ fields (listed in are overridden by a command line argument. For example, to provide an ``email`` field, you can use ``DJANGO_SUPERUSER_EMAIL`` environment variable. -.. versionchanged:: 3.0 - - Support for using ``DJANGO_SUPERUSER_PASSWORD`` and - ``DJANGO_SUPERUSER_`` environment variables was added. - .. django-admin-option:: --noinput, --no-input Suppresses all user prompts. If a suppressed prompt cannot be resolved @@ -1825,8 +1805,6 @@ colored output to another command. .. django-admin-option:: --skip-checks -.. versionadded:: 3.0 - Skips running system checks prior to running the command. This option is only available if the :attr:`~django.core.management.BaseCommand.requires_system_checks` command diff --git a/docs/ref/exceptions.txt b/docs/ref/exceptions.txt index 6b8d6707e41e..ee2c9b7f10b6 100644 --- a/docs/ref/exceptions.txt +++ b/docs/ref/exceptions.txt @@ -167,8 +167,6 @@ list of errors. .. exception:: RequestAborted - .. versionadded:: 3.0 - The :exc:`RequestAborted` exception is raised when a HTTP body being read in by the handler is cut off midstream and the client connection closes, or when the client does not send data and hits a timeout where the server @@ -184,8 +182,6 @@ list of errors. .. exception:: SynchronousOnlyOperation - .. versionadded:: 3.0 - The :exc:`SynchronousOnlyOperation` exception is raised when code that is only allowed in synchronous Python code is called from an asynchronous context (a thread with a running asynchronous event loop). These parts of diff --git a/docs/ref/files/storage.txt b/docs/ref/files/storage.txt index 542eb2dc7ed6..03ec71a2ad1f 100644 --- a/docs/ref/files/storage.txt +++ b/docs/ref/files/storage.txt @@ -112,8 +112,6 @@ The ``Storage`` class .. method:: get_alternative_name(file_root, file_ext) - .. versionadded:: 3.0 - Returns an alternative filename based on the ``file_root`` and ``file_ext`` parameters, an underscore plus a random 7 character alphanumeric string is appended to the filename before the extension. diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt index 0e51dec75cde..c52bcc5d1889 100644 --- a/docs/ref/middleware.txt +++ b/docs/ref/middleware.txt @@ -247,8 +247,6 @@ __ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Se Referrer Policy ~~~~~~~~~~~~~~~ -.. versionadded:: 3.0 - Browsers use `the Referer header`__ as a way to send information to a site about how users got there. When a user clicks a link, the browser will send the full URL of the linking page as the referrer. While this can be useful for some diff --git a/docs/ref/models/conditional-expressions.txt b/docs/ref/models/conditional-expressions.txt index 69a45d662b2a..7616b98e0a92 100644 --- a/docs/ref/models/conditional-expressions.txt +++ b/docs/ref/models/conditional-expressions.txt @@ -48,10 +48,6 @@ objects that have an ``output_field`` that is a :class:`~django.db.models.BooleanField`. The result is provided using the ``then`` keyword. -.. versionchanged:: 3.0 - - Support for boolean :class:`~django.db.models.Expression` was added. - Some examples:: >>> from django.db.models import F, Q, When @@ -252,8 +248,6 @@ The two SQL statements are functionally equivalent but the more explicit Conditional filter ------------------ -.. versionadded:: 3.0 - When a conditional expression returns a boolean value, it is possible to use it directly in filters. This means that it will not be added to the ``SELECT`` columns, but you can still use it to filter results:: diff --git a/docs/ref/models/constraints.txt b/docs/ref/models/constraints.txt index 00e907a88274..ed5653660609 100644 --- a/docs/ref/models/constraints.txt +++ b/docs/ref/models/constraints.txt @@ -69,10 +69,6 @@ ensures the age field is never less than 18. The name of the constraint. -.. versionchanged:: 3.0 - - Interpolation of ``'%(app_label)s'`` and ``'%(class)s'`` was added. - ``UniqueConstraint`` ==================== @@ -99,10 +95,6 @@ date. The name of the constraint. -.. versionchanged:: 3.0 - - Interpolation of ``'%(app_label)s'`` and ``'%(class)s'`` was added. - ``condition`` ------------- diff --git a/docs/ref/models/database-functions.txt b/docs/ref/models/database-functions.txt index b702085e77f5..da67d9e362d5 100644 --- a/docs/ref/models/database-functions.txt +++ b/docs/ref/models/database-functions.txt @@ -479,10 +479,6 @@ The ``is_dst`` parameter indicates whether or not ``pytz`` should interpret nonexistent and ambiguous datetimes in daylight saving time. By default (when ``is_dst=None``), ``pytz`` raises an exception for such datetimes. -.. versionadded:: 3.0 - - The ``is_dst`` parameter was added. - Given the datetime ``2015-06-15 14:30:50.000321+00:00``, the built-in ``kind``\s return: @@ -1120,8 +1116,6 @@ It can also be registered as a transform. For example:: .. class:: Sign(expression, **extra) -.. versionadded:: 3.0 - Returns the sign (-1, 0, 1) of a numeric field or expression. Usage example:: @@ -1357,8 +1351,6 @@ spaces. .. class:: MD5(expression, **extra) -.. versionadded:: 3.0 - Accepts a single text field or expression and returns the MD5 hash of the string. @@ -1489,8 +1481,6 @@ spaces. .. class:: SHA384(expression, **extra) .. class:: SHA512(expression, **extra) -.. versionadded:: 3.0 - Accepts a single text field or expression and returns the particular hash of the string. diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index e4a186fcdc12..252966bb6cbc 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -641,13 +641,6 @@ directly filter a queryset:: This will ensure that the subquery will not be added to the ``SELECT`` columns, which may result in a better performance. -.. versionchanged:: 3.0 - - In previous versions of Django, it was necessary to first annotate and then - filter against the annotation. This resulted in the annotated value always - being present in the query result, and often resulted in a query that took - more time to execute. - Using aggregates within a ``Subquery`` expression ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -995,10 +988,6 @@ calling the appropriate methods on the wrapped expression. to a column. The ``alias`` parameter will be ``None`` unless the expression has been annotated and is used for grouping. - .. versionchanged:: 3.0 - - The ``alias`` parameter was added. - .. method:: asc(nulls_first=False, nulls_last=False) Returns the expression ready to be sorted in ascending order. diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 452736dfa898..a72c9b386262 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -301,10 +301,6 @@ There are some additional caveats to be aware of: __empty__ = _('(Unknown)') -.. versionadded:: 3.0 - - The ``TextChoices``, ``IntegerChoices``, and ``Choices`` classes were added. - ``db_column`` ------------- @@ -816,10 +812,6 @@ Has two optional arguments: class MyModel(models.Model): upload = models.FileField(upload_to=user_directory_path) - .. versionchanged:: 3.0 - - Support for :class:`pathlib.Path` was added. - .. attribute:: FileField.storage A storage object, or a callable which returns a storage object. This @@ -1030,10 +1022,6 @@ directory on the filesystem. Has some special arguments, of which the first is class MyModel(models.Model): file = models.FilePathField(path=images_path) - .. versionchanged:: 3.0 - - ``path`` can now be a callable. - .. attribute:: FilePathField.match Optional. A regular expression, as a string, that :class:`FilePathField` @@ -1315,8 +1303,6 @@ It uses :class:`~django.core.validators.validate_slug` or .. class:: SmallAutoField(**options) -.. versionadded:: 3.0 - Like an :class:`AutoField`, but only allows values under a certain (database-dependent) limit. Values from ``1`` to ``32767`` are safe in all databases supported by Django. @@ -1820,11 +1806,6 @@ that control how the relationship functions. add the descriptor for the reverse relationship, allowing :class:`ManyToManyField` relationships to be non-symmetrical. - .. versionchanged:: 3.0 - - Specifying ``symmetrical=True`` for recursive many-to-many - relationships using an intermediary model was allowed. - .. attribute:: ManyToManyField.through Django will automatically generate a table to manage many-to-many @@ -2078,8 +2059,6 @@ Field API reference .. attribute:: descriptor_class - .. versionadded:: 3.0 - A class implementing the :py:ref:`descriptor protocol ` that is instantiated and assigned to the model instance attribute. The constructor must accept a single argument, the ``Field`` instance. diff --git a/docs/ref/models/indexes.txt b/docs/ref/models/indexes.txt index ae872605a139..c4bcdff0ddb3 100644 --- a/docs/ref/models/indexes.txt +++ b/docs/ref/models/indexes.txt @@ -61,10 +61,6 @@ than 30 characters and shouldn't start with a number (0-9) or underscore (_). concrete model. For example ``Index(fields=['title'], name='%(app_label)s_%(class)s_title_index')``. -.. versionchanged:: 3.0 - - Interpolation of ``'%(app_label)s'`` and ``'%(class)s'`` was added. - ``db_tablespace`` ----------------- diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 06c63eba0456..1da38d96632d 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -496,12 +496,6 @@ which returns ``NULL``. In such cases it is possible to revert to the old algorithm by setting the :attr:`~django.db.models.Options.select_on_save` option to ``True``. -.. versionchanged:: 3.0 - - ``Model.save()`` no longer attempts to find a row when saving a new - ``Model`` instance and a default value for the primary key is provided, and - always executes an ``INSERT``. - .. _ref-models-force-insert: Forcing an INSERT or UPDATE diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 784d22ce4b43..b96cd67e9808 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -3455,10 +3455,6 @@ by the aggregate. This is the SQL equivalent of ``AVG(DISTINCT )``. The default value is ``False``. - .. versionchanged:: 3.0 - - Support for ``distinct=True`` was added. - ``Count`` ~~~~~~~~~ @@ -3534,10 +3530,6 @@ by the aggregate. the SQL equivalent of ``SUM(DISTINCT )``. The default value is ``False``. - .. versionchanged:: 3.0 - - Support for ``distinct=True`` was added. - ``Variance`` ~~~~~~~~~~~~ diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index a769af581b47..ad57038e5ae5 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -202,10 +202,6 @@ All attributes should be considered read-only, unless stated otherwise. {{ request.headers.user_agent }} - .. versionchanged:: 3.0 - - Support for lookups using underscores was added. - .. attribute:: HttpRequest.resolver_match An instance of :class:`~django.urls.ResolverMatch` representing the @@ -684,10 +680,6 @@ or :class:`memoryview`, to the :class:`HttpResponse` constructor:: >>> response = HttpResponse(b'Bytestrings are also accepted.') >>> response = HttpResponse(memoryview(b'Memoryview as well.')) -.. versionchanged:: 3.0 - - Support for :class:`memoryview` was added. - But if you want to add content incrementally, you can use ``response`` as a file-like object:: @@ -812,10 +804,6 @@ Methods given it will be extracted from ``content_type``, and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. - .. versionchanged:: 3.0 - - Support for :class:`memoryview` ``content`` was added. - .. method:: HttpResponse.__setitem__(header, value) Sets the given header name to the given value. Both ``header`` and diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 10e7ab8a6e6c..46df532859b7 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -1561,10 +1561,6 @@ when using the :djadmin:`collectstatic` management command. See way that modes must be specified. If you try to use ``644``, you'll get totally incorrect behavior. -.. versionchanged:: 3.0 - - In older versions, the default value is ``None``. - .. setting:: FILE_UPLOAD_TEMP_DIR ``FILE_UPLOAD_TEMP_DIR`` @@ -1823,8 +1819,6 @@ deletes the old one. ``LANGUAGE_COOKIE_HTTPONLY`` ---------------------------- -.. versionadded:: 3.0 - Default: ``False`` Whether to use ``HttpOnly`` flag on the language cookie. If this is set to @@ -1872,8 +1866,6 @@ deletes the one. ``LANGUAGE_COOKIE_SAMESITE`` ---------------------------- -.. versionadded:: 3.0 - Default: ``None`` The value of the `SameSite`_ flag on the language cookie. This flag prevents the @@ -1890,8 +1882,6 @@ See :setting:`SESSION_COOKIE_SAMESITE` for details about ``SameSite``. ``LANGUAGE_COOKIE_SECURE`` -------------------------- -.. versionadded:: 3.0 - Default: ``False`` Whether to use a secure cookie for the language cookie. If this is set to @@ -2263,10 +2253,6 @@ If ``True``, the :class:`~django.middleware.security.SecurityMiddleware` sets the :ref:`x-content-type-options` header on all responses that do not already have it. -.. versionchanged:: 3.0 - - In older versions, the default value is ``False``. - .. setting:: SECURE_HSTS_INCLUDE_SUBDOMAINS ``SECURE_HSTS_INCLUDE_SUBDOMAINS`` @@ -2393,8 +2379,6 @@ from URL paths, so patterns shouldn't include them, e.g. ``SECURE_REFERRER_POLICY`` -------------------------- -.. versionadded:: 3.0 - Default: ``'same-origin'`` If configured, the :class:`~django.middleware.security.SecurityMiddleware` sets @@ -2887,10 +2871,6 @@ The default value for the X-Frame-Options header used by :class:`~django.middleware.clickjacking.XFrameOptionsMiddleware`. See the :doc:`clickjacking protection ` documentation. -.. versionchanged:: 3.0 - - In older versions, the default value is ``SAMEORIGIN``. - Auth ==== diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 4599331093a5..dcc354e2e2b8 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -71,21 +71,13 @@ need to distinguish caches by the ``Accept-language`` header. private`` header to a response to indicate that a page should never be cached. - .. versionchanged:: 3.0 - - ``private`` directive was added. - .. function:: patch_vary_headers(response, newheaders) Adds (or updates) the ``Vary`` header in the given ``HttpResponse`` object. ``newheaders`` is a list of header names that should be in ``Vary``. If headers contains an asterisk, then ``Vary`` header will consist of a single - asterisk ``'*'``. Otherwise, existing headers in ``Vary`` aren't removed. - - .. versionchanged:: 3.0 - - Handling an asterisk ``'*'`` according to :rfc:`7231#section-7.1.4` was - added. + asterisk ``'*'``, according to :rfc:`7231#section-7.1.4`. Otherwise, + existing headers in ``Vary`` aren't removed. .. function:: get_cache_key(request, key_prefix=None, method='GET', cache=None) @@ -643,11 +635,6 @@ escaping HTML. for use in HTML. The input is first coerced to a string and the output has :func:`~django.utils.safestring.mark_safe` applied. - .. versionchanged:: 3.0 - - In older versions, ``'`` is converted to its decimal code ``'`` - instead of the equivalent hex code ``'``. - .. function:: conditional_escape(text) Similar to ``escape()``, except that it doesn't operate on pre-escaped diff --git a/docs/topics/async.txt b/docs/topics/async.txt index 99b7f0611379..b3bd285afe17 100644 --- a/docs/topics/async.txt +++ b/docs/topics/async.txt @@ -2,8 +2,6 @@ Asynchronous support ==================== -.. versionadded:: 3.0 - .. currentmodule:: asgiref.sync Django has support for writing asynchronous ("async") views, along with an diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index 6b816c42fdbd..6ab830546882 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -577,14 +577,6 @@ password resets. You must then provide some key implementation details: ``REQUIRED_FIELDS`` has no effect in other parts of Django, like creating a user in the admin. - .. versionadded:: 3.0 - - :attr:`REQUIRED_FIELDS` now supports - :class:`~django.db.models.ManyToManyField`\s without a custom - through model. Since there is no way to pass model instances during - the :djadmin:`createsuperuser` prompt, expect the user to enter IDs - of existing instances of the class to which the model is related. - For example, here is the partial definition for a user model that defines two required fields - a date of birth and height:: @@ -934,8 +926,6 @@ methods and attributes: .. method:: models.PermissionsMixin.get_user_permissions(obj=None) - .. versionadded:: 3.0 - Returns a set of permission strings that the user has directly. If ``obj`` is passed in, only returns the user permissions for this diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index dab12ca59297..be45723bde4f 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -1398,10 +1398,6 @@ implementation details see :ref:`using-the-views`. * ``reset_url_token``: Token parameter displayed as a component of password reset URLs. Defaults to ``'set-password'``. - .. versionchanged:: 3.0 - - The ``reset_url_token`` class attribute was added. - **Template context:** * ``form``: The form (see ``form_class`` above) for setting the new user's diff --git a/docs/topics/forms/formsets.txt b/docs/topics/forms/formsets.txt index 2f3e4403f683..3b5775cabb5c 100644 --- a/docs/topics/forms/formsets.txt +++ b/docs/topics/forms/formsets.txt @@ -459,8 +459,6 @@ control the widget used with ``ordering_widget`` ^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 3.0 - .. attribute:: BaseFormSet.ordering_widget Default: :class:`~django.forms.NumberInput` @@ -478,8 +476,6 @@ Set ``ordering_widget`` to specify the widget class to be used with ``get_ordering_widget`` ^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 3.0 - .. method:: BaseFormSet.get_ordering_widget() Override ``get_ordering_widget()`` if you need to provide a widget instance for diff --git a/docs/topics/http/decorators.txt b/docs/topics/http/decorators.txt index e1ec2c602841..fe91d0cc9875 100644 --- a/docs/topics/http/decorators.txt +++ b/docs/topics/http/decorators.txt @@ -121,7 +121,3 @@ client-side caching. This decorator adds a ``Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private`` header to a response to indicate that a page should never be cached. - - .. versionchanged:: 3.0 - - ``private`` directive was added. diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt index 9427ac016938..41c2c499e4b7 100644 --- a/docs/topics/http/sessions.txt +++ b/docs/topics/http/sessions.txt @@ -246,8 +246,6 @@ You can edit it multiple times. .. method:: get_session_cookie_age() - .. versionadded:: 3.0 - Returns the age of session cookies, in seconds. Defaults to :setting:`SESSION_COOKIE_AGE`. diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt index ff39635c9ce2..31671db81d6e 100644 --- a/docs/topics/http/urls.txt +++ b/docs/topics/http/urls.txt @@ -61,11 +61,6 @@ algorithm the system follows to determine which Python code to execute: in the optional ``kwargs`` argument to :func:`django.urls.path` or :func:`django.urls.re_path`. - .. versionchanged:: 3.0 - - In older versions, the keyword arguments with ``None`` values are - made up also for not provided named parts. - #. If no URL pattern matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view. See `Error handling`_ below. diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 5fdf8f0a4ebb..7afe47c14987 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -1854,10 +1854,6 @@ You would typically want to use both: :func:`django.utils.translation.activate() changes the language for this thread, and setting the cookie makes this preference persist in future requests. -.. versionchanged:: 3.0 - - In older versions, you could set the language in the current session. - Using translations outside views and templates ---------------------------------------------- diff --git a/docs/topics/logging.txt b/docs/topics/logging.txt index 2b2c33208aab..e8c59150a03e 100644 --- a/docs/topics/logging.txt +++ b/docs/topics/logging.txt @@ -693,10 +693,6 @@ Python logging module. } }, - .. versionadded:: 3.0 - - The ``reporter_class`` argument was added. - .. method:: send_mail(subject, message, *args, **kwargs) Sends emails to admin users. To customize this behavior, you can diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index dd9fa5eb1c09..b14a17398799 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -132,10 +132,6 @@ Use the ``django.test.Client`` class to make requests. exceptions raised during the request should also be raised in the test. Defaults to ``True``. - .. versionadded:: 3.0 - - The ``raise_request_exception`` argument was added. - Once you have a ``Client`` instance, you can call any of the following methods: @@ -481,8 +477,6 @@ Specifically, a ``Response`` object has the following attributes: .. attribute:: exc_info - .. versionadded:: 3.0 - A tuple of three values that provides information about the unhandled exception, if any, that occurred during the view. From d106d07f732013eeb4667e73fa9cfd197e1d3484 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Mon, 4 May 2020 12:07:45 +0200 Subject: [PATCH 0004/1251] Advanced deprecation warnings for Django 3.2. --- django/utils/deprecation.py | 7 +++++-- docs/internals/deprecation.txt | 8 ++++++++ tests/runtests.py | 5 ++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py index 6336558a817b..3582fcf3a31b 100644 --- a/django/utils/deprecation.py +++ b/django/utils/deprecation.py @@ -5,14 +5,17 @@ from asgiref.sync import sync_to_async -class RemovedInNextVersionWarning(DeprecationWarning): +class RemovedInDjango40Warning(DeprecationWarning): pass -class RemovedInDjango40Warning(PendingDeprecationWarning): +class RemovedInDjango41Warning(PendingDeprecationWarning): pass +RemovedInNextVersionWarning = RemovedInDjango40Warning + + class warn_about_renamed_method: def __init__(self, class_name, old_method_name, new_method_name, deprecation_warning): self.class_name = class_name diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 074345ef4032..e48356bed1c7 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -7,6 +7,14 @@ in a backward incompatible way, following their deprecation, as per the :ref:`deprecation policy `. More details about each item can often be found in the release notes of two versions prior. +.. _deprecation-removed-in-4.1: + +4.1 +--- + +See the :ref:`Django 3.2 release notes ` for more +details on these changes. + .. _deprecation-removed-in-4.0: 4.0 diff --git a/tests/runtests.py b/tests/runtests.py index 8264d4068441..d79b4b393e48 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -24,7 +24,9 @@ from django.test.runner import default_test_processes from django.test.selenium import SeleniumTestCaseBase from django.test.utils import get_runner - from django.utils.deprecation import RemovedInDjango40Warning + from django.utils.deprecation import ( + RemovedInDjango40Warning, RemovedInDjango41Warning, + ) from django.utils.log import DEFAULT_LOGGING from django.utils.version import PY37 @@ -38,6 +40,7 @@ # Make deprecation warnings errors to ensure no usage of deprecated features. warnings.simplefilter("error", RemovedInDjango40Warning) +warnings.simplefilter('error', RemovedInDjango41Warning) # Make resource and runtime warning errors to ensure no usage of error prone # patterns. warnings.simplefilter("error", ResourceWarning) From f2187a227f7a3c80282658e699ae9b04023724e5 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Mon, 4 May 2020 12:19:16 +0200 Subject: [PATCH 0005/1251] Increased the default PBKDF2 iterations for Django 3.2. --- django/contrib/auth/hashers.py | 2 +- docs/releases/3.2.txt | 3 ++- tests/auth_tests/test_hashers.py | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index 66fb94e7af01..29cba3fd5c11 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -241,7 +241,7 @@ class PBKDF2PasswordHasher(BasePasswordHasher): safely but you must rename the algorithm if you change SHA256. """ algorithm = "pbkdf2_sha256" - iterations = 216000 + iterations = 260000 digest = hashlib.sha256 def encode(self, password, salt, iterations=None): diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt index 41e820434570..3950a70e7272 100644 --- a/docs/releases/3.2.txt +++ b/docs/releases/3.2.txt @@ -47,7 +47,8 @@ Minor features :mod:`django.contrib.auth` ~~~~~~~~~~~~~~~~~~~~~~~~~~ -* ... +* The default iteration count for the PBKDF2 password hasher is increased from + 216,000 to 260,000. :mod:`django.contrib.contenttypes` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py index 05be565fedc2..01b1e3543913 100644 --- a/tests/auth_tests/test_hashers.py +++ b/tests/auth_tests/test_hashers.py @@ -63,7 +63,7 @@ def test_invalid_password(self): def test_pbkdf2(self): encoded = make_password('lètmein', 'seasalt', 'pbkdf2_sha256') - self.assertEqual(encoded, 'pbkdf2_sha256$216000$seasalt$youGZxOw6ZOcfrXv2i8/AhrnpZflJJ9EshS9XmUJTUg=') + self.assertEqual(encoded, 'pbkdf2_sha256$260000$seasalt$YlZ2Vggtqdc61YjArZuoApoBh9JNGYoDRBUGu6tcJQo=') self.assertTrue(is_password_usable(encoded)) self.assertTrue(check_password('lètmein', encoded)) self.assertFalse(check_password('lètmeinz', encoded)) @@ -296,13 +296,13 @@ def test_is_password_usable(self): def test_low_level_pbkdf2(self): hasher = PBKDF2PasswordHasher() encoded = hasher.encode('lètmein', 'seasalt2') - self.assertEqual(encoded, 'pbkdf2_sha256$216000$seasalt2$gHyszNJ9lwTG5y3MQUjZe+OJmYVTBPl/y7bYq9dtk8M=') + self.assertEqual(encoded, 'pbkdf2_sha256$260000$seasalt2$UCGMhrOoaq1ghQPArIBK5RkI6IZLRxlIwHWA1dMy7y8=') self.assertTrue(hasher.verify('lètmein', encoded)) def test_low_level_pbkdf2_sha1(self): hasher = PBKDF2SHA1PasswordHasher() encoded = hasher.encode('lètmein', 'seasalt2') - self.assertEqual(encoded, 'pbkdf2_sha1$216000$seasalt2$E1KH89wMKuPXrrQzifVcG4cBtiA=') + self.assertEqual(encoded, 'pbkdf2_sha1$260000$seasalt2$wAibXvW6jgvatCdONi6SMJ6q7mI=') self.assertTrue(hasher.verify('lètmein', encoded)) @override_settings( From 05ed7104c0bc069352b2cee85ab918e48ee73cbe Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Wed, 13 May 2020 00:09:07 -0700 Subject: [PATCH 0006/1251] Fixed numbered list in admin overview docs. --- docs/ref/contrib/admin/index.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 1dd7812c419d..420dac182b97 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -44,7 +44,7 @@ If you're not using the default project template, here are the requirements: :class:`django.contrib.messages.middleware.MessageMiddleware` must be included. -5. :ref:`Hook the admin's URLs into your URLconf +#. :ref:`Hook the admin's URLs into your URLconf `. After you've taken these steps, you'll be able to use the admin site by From 7cd88b3fece1c17f5ee905c78222a28594fee215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 13 May 2020 07:12:18 +0000 Subject: [PATCH 0007/1251] Updated logging calls to use arguments instead of string interpolation. --- django/core/handlers/base.py | 2 +- django/utils/autoreload.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index e7fbaf594e2f..de0dd6f018af 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -117,7 +117,7 @@ def adapt_method_mode( return sync_to_async(method, thread_sensitive=True) elif method_is_async: if debug: - logger.debug('Asynchronous %s adapted.' % name) + logger.debug('Asynchronous %s adapted.', name) return async_to_sync(method) return method diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index 845c46c8d44b..873f3d8367c7 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -145,7 +145,7 @@ def iter_modules_and_files(modules, extra_files): continue except ValueError as e: # Network filesystems may return null bytes in file paths. - logger.debug('"%s" raised when resolving path: "%s"' % (str(e), path)) + logger.debug('"%s" raised when resolving path: "%s"', e, path) continue results.add(resolved_path) return frozenset(results) From c8bebbd541d601ed283617166609b37d2ccd7f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 13 May 2020 07:12:43 +0000 Subject: [PATCH 0008/1251] Disabled management commands output with verbosity 0 in various tests. --- tests/auth_tests/test_management.py | 3 +-- tests/migrate_signals/tests.py | 11 ++++------- tests/swappable_models/tests.py | 5 +---- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 0acdb4ece24d..eb2be26dc3ff 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -310,13 +310,12 @@ def test_verbosity_zero(self): self.assertFalse(u.has_usable_password()) def test_email_in_username(self): - new_io = StringIO() call_command( "createsuperuser", interactive=False, username="joe+admin@somewhere.org", email="joe@somewhere.org", - stdout=new_io + verbosity=0, ) u = User._default_manager.get(username="joe+admin@somewhere.org") self.assertEqual(u.email, 'joe@somewhere.org') diff --git a/tests/migrate_signals/tests.py b/tests/migrate_signals/tests.py index 563be2a82d1c..9611fc90e15c 100644 --- a/tests/migrate_signals/tests.py +++ b/tests/migrate_signals/tests.py @@ -1,5 +1,3 @@ -from io import StringIO - from django.apps import apps from django.core import management from django.db import migrations @@ -9,7 +7,7 @@ APP_CONFIG = apps.get_app_config('migrate_signals') SIGNAL_ARGS = ['app_config', 'verbosity', 'interactive', 'using', 'plan', 'apps'] MIGRATE_DATABASE = 'default' -MIGRATE_VERBOSITY = 1 +MIGRATE_VERBOSITY = 0 MIGRATE_INTERACTIVE = False @@ -71,7 +69,7 @@ def test_args(self): post_migrate_receiver = Receiver(signals.post_migrate) management.call_command( 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY, - interactive=MIGRATE_INTERACTIVE, stdout=StringIO(), + interactive=MIGRATE_INTERACTIVE, ) for receiver in [pre_migrate_receiver, post_migrate_receiver]: @@ -92,10 +90,9 @@ def test_migrations_only(self): """ pre_migrate_receiver = Receiver(signals.pre_migrate) post_migrate_receiver = Receiver(signals.post_migrate) - stdout = StringIO() management.call_command( 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY, - interactive=MIGRATE_INTERACTIVE, stdout=stdout, + interactive=MIGRATE_INTERACTIVE, ) for receiver in [pre_migrate_receiver, post_migrate_receiver]: args = receiver.call_args @@ -119,7 +116,7 @@ def test_migrations_only(self): post_migrate_receiver = Receiver(signals.post_migrate) management.call_command( 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY, - interactive=MIGRATE_INTERACTIVE, stdout=stdout, + interactive=MIGRATE_INTERACTIVE, ) self.assertEqual( [model._meta.label for model in pre_migrate_receiver.call_args['apps'].get_models()], diff --git a/tests/swappable_models/tests.py b/tests/swappable_models/tests.py index bdf681dd87de..b1bcaa9f70e5 100644 --- a/tests/swappable_models/tests.py +++ b/tests/swappable_models/tests.py @@ -1,5 +1,3 @@ -from io import StringIO - from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.core import management @@ -26,8 +24,7 @@ def test_generated_data(self): ContentType.objects.filter(app_label='swappable_models').delete() # Re-run migrate. This will re-build the permissions and content types. - new_io = StringIO() - management.call_command('migrate', interactive=False, stdout=new_io) + management.call_command('migrate', interactive=False, verbosity=0) # Content types and permissions exist for the swapped model, # but not for the swappable model. From f9d13a1b5a637434556f88b0703087bf98ce3211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 13 May 2020 07:13:02 +0000 Subject: [PATCH 0009/1251] Removed unused fixture2.xml from fixtures_model_package tests. --- tests/fixtures_model_package/fixtures/fixture2.xml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 tests/fixtures_model_package/fixtures/fixture2.xml diff --git a/tests/fixtures_model_package/fixtures/fixture2.xml b/tests/fixtures_model_package/fixtures/fixture2.xml deleted file mode 100644 index 55337cf81086..000000000000 --- a/tests/fixtures_model_package/fixtures/fixture2.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - Poker on TV is great! - 2006-06-16 11:00:00 - - - XML identified as leading cause of cancer - 2006-06-16 16:00:00 - - From a9337b4add01e50ed8ff8d3ef44099a08cba475c Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Thu, 30 Apr 2020 10:30:11 +0100 Subject: [PATCH 0010/1251] Used :pep: role in various docs. --- docs/howto/deployment/wsgi/index.txt | 8 ++++---- docs/internals/contributing/writing-documentation.txt | 4 ++++ docs/ref/files/uploads.txt | 8 +++----- docs/ref/request-response.txt | 7 +++---- docs/releases/1.6.txt | 2 +- docs/releases/1.8.txt | 8 +++----- docs/topics/db/transactions.txt | 5 ++--- 7 files changed, 20 insertions(+), 22 deletions(-) diff --git a/docs/howto/deployment/wsgi/index.txt b/docs/howto/deployment/wsgi/index.txt index c7416b84fdce..fae2d69980f2 100644 --- a/docs/howto/deployment/wsgi/index.txt +++ b/docs/howto/deployment/wsgi/index.txt @@ -70,8 +70,10 @@ If this variable isn't set, the default :file:`wsgi.py` sets it to Applying WSGI middleware ======================== -To apply `WSGI middleware`_ you can wrap the application object. For instance -you could add these lines at the bottom of :file:`wsgi.py`:: +To apply :pep:`WSGI middleware +<3333#middleware-components-that-play-both-sides>` you can wrap the application +object. For instance you could add these lines at the bottom of +:file:`wsgi.py`:: from helloworld.wsgi import HelloWorldApplication application = HelloWorldApplication(application) @@ -79,5 +81,3 @@ you could add these lines at the bottom of :file:`wsgi.py`:: You could also replace the Django WSGI application with a custom WSGI application that later delegates to the Django WSGI application, if you want to combine a Django application with a WSGI application of another framework. - -.. _`WSGI middleware`: https://www.python.org/dev/peps/pep-3333/#middleware-components-that-play-both-sides diff --git a/docs/internals/contributing/writing-documentation.txt b/docs/internals/contributing/writing-documentation.txt index 5036f30fe023..91b81e467319 100644 --- a/docs/internals/contributing/writing-documentation.txt +++ b/docs/internals/contributing/writing-documentation.txt @@ -239,6 +239,10 @@ documentation: section if possible. For example, use ``:rfc:`2324#section-2.3.2``` or ``:rfc:`Custom link text <2324#section-2.3.2>```. +* Use :rst:role:`:pep:` to reference a Python Enhancement Proposal (PEP) + and try to link to the relevant section if possible. For example, use + ``:pep:`20#easter-egg``` or ``:pep:`Easter Egg <20#easter-egg>```. + Django-specific markup ====================== diff --git a/docs/ref/files/uploads.txt b/docs/ref/files/uploads.txt index 0021800a641a..4ce4eb991add 100644 --- a/docs/ref/files/uploads.txt +++ b/docs/ref/files/uploads.txt @@ -76,11 +76,9 @@ Here are some useful attributes of ``UploadedFile``: for line in uploadedfile: do_something_with(line) - Lines are split using `universal newlines`_. The following are recognized - as ending a line: the Unix end-of-line convention ``'\n'``, the Windows - convention ``'\r\n'``, and the old Macintosh convention ``'\r'``. - - .. _universal newlines: https://www.python.org/dev/peps/pep-0278 + Lines are split using :pep:`universal newlines <278>`. The following are + recognized as ending a line: the Unix end-of-line convention ``'\n'``, the + Windows convention ``'\r\n'``, and the old Macintosh convention ``'\r'``. Subclasses of ``UploadedFile`` include: diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index ad57038e5ae5..17c0f303354e 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -1161,8 +1161,9 @@ Attributes .. class:: FileResponse(open_file, as_attachment=False, filename='', **kwargs) :class:`FileResponse` is a subclass of :class:`StreamingHttpResponse` - optimized for binary files. It uses `wsgi.file_wrapper`_ if provided by the - wsgi server, otherwise it streams the file out in small chunks. + optimized for binary files. It uses :pep:`wsgi.file_wrapper + <3333#optional-platform-specific-file-handling>` if provided by the wsgi + server, otherwise it streams the file out in small chunks. If ``as_attachment=True``, the ``Content-Disposition`` header is set to ``attachment``, which asks the browser to offer the file to the user as a @@ -1178,8 +1179,6 @@ Attributes The ``Content-Length`` and ``Content-Type`` headers are automatically set when they can be guessed from contents of ``open_file``. -.. _wsgi.file_wrapper: https://www.python.org/dev/peps/pep-3333/#optional-platform-specific-file-handling - ``FileResponse`` accepts any file-like object with binary content, for example a file open in binary mode like so:: diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 71457f15f678..304c12c3249d 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -173,7 +173,7 @@ Minor features * In addition to :lookup:`year`, :lookup:`month` and :lookup:`day`, the ORM now supports :lookup:`hour`, :lookup:`minute` and :lookup:`second` lookups. -* Django now wraps all PEP-249 exceptions. +* Django now wraps all :pep:`249` exceptions. * The default widgets for :class:`~django.forms.EmailField`, :class:`~django.forms.URLField`, :class:`~django.forms.IntegerField`, diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 384517682779..ab57349e0905 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -1123,11 +1123,9 @@ Miscellaneous check framework (unless you pass it ``skip_checks=False``). * When iterating over lines, :class:`~django.core.files.File` now uses - `universal newlines`_. The following are recognized as ending a line: the - Unix end-of-line convention ``'\n'``, the Windows convention ``'\r\n'``, and - the old Macintosh convention ``'\r'``. - - .. _universal newlines: https://www.python.org/dev/peps/pep-0278 + :pep:`universal newlines <278>`. The following are recognized as ending a + line: the Unix end-of-line convention ``'\n'``, the Windows convention + ``'\r\n'``, and the old Macintosh convention ``'\r'``. * The Memcached cache backends ``MemcachedCache`` and ``PyLibMCCache`` will delete a key if ``set()`` fails. This is necessary to ensure the ``cache_db`` diff --git a/docs/topics/db/transactions.txt b/docs/topics/db/transactions.txt index 40a36e777d1a..44a21e5ee245 100644 --- a/docs/topics/db/transactions.txt +++ b/docs/topics/db/transactions.txt @@ -369,8 +369,8 @@ etc.), this should be fine. If it's not (if your follow-up action is so critical that its failure should mean the failure of the transaction itself), then you don't want to use the :func:`on_commit` hook. Instead, you may want `two-phase commit`_ such as the :ref:`psycopg Two-Phase Commit protocol support -` and the `optional Two-Phase Commit Extensions in the Python -DB-API specification`_. +` and the :pep:`optional Two-Phase Commit Extensions in the +Python DB-API specification <249#optional-two-phase-commit-extensions>`. Callbacks are not run until autocommit is restored on the connection following the commit (because otherwise any queries done in a callback would open an @@ -387,7 +387,6 @@ autocommit is disabled and you are not within an atomic block will result in an error. .. _two-phase commit: https://en.wikipedia.org/wiki/Two-phase_commit_protocol -.. _optional Two-Phase Commit Extensions in the Python DB-API specification: https://www.python.org/dev/peps/pep-0249/#optional-two-phase-commit-extensions Use in tests ------------ From feb91dbda13974f84eac52dccdc0de1ddb636616 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Thu, 30 Apr 2020 10:33:04 +0100 Subject: [PATCH 0011/1251] Used :mimetype: role in various docs. --- .../contributing/writing-documentation.txt | 3 +++ docs/ref/request-response.txt | 2 +- docs/releases/1.11.txt | 4 ++-- docs/releases/1.5.txt | 10 +++++----- docs/releases/1.7.txt | 4 +++- docs/topics/auth/default.txt | 4 ++-- docs/topics/email.txt | 17 +++++++++-------- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/docs/internals/contributing/writing-documentation.txt b/docs/internals/contributing/writing-documentation.txt index 91b81e467319..bd9d0e9495da 100644 --- a/docs/internals/contributing/writing-documentation.txt +++ b/docs/internals/contributing/writing-documentation.txt @@ -243,6 +243,9 @@ documentation: and try to link to the relevant section if possible. For example, use ``:pep:`20#easter-egg``` or ``:pep:`Easter Egg <20#easter-egg>```. +* Use :rst:role:`:mimetype:` to refer to a MIME Type unless the value + is quoted for a code example. + Django-specific markup ====================== diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index 17c0f303354e..d53b7180207d 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -1028,7 +1028,7 @@ can create it with the help of :py:class:`http.HTTPStatus`. For example:: response. It inherits most behavior from its superclass with a couple differences: - Its default ``Content-Type`` header is set to ``application/json``. + Its default ``Content-Type`` header is set to :mimetype:`application/json`. The first parameter, ``data``, should be a ``dict`` instance. If the ``safe`` parameter is set to ``False`` (see below) it can be any diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt index f45e7ba38f95..805476c3489a 100644 --- a/docs/releases/1.11.txt +++ b/docs/releases/1.11.txt @@ -275,8 +275,8 @@ Email headers in the local time zone rather than in UTC. * ``EmailMessage.attach()`` and ``attach_file()`` now fall back to MIME type - ``application/octet-stream`` when binary content that can't be decoded as - UTF-8 is specified for a ``text/*`` attachment. + :mimetype:`application/octet-stream` when binary content that can't be + decoded as UTF-8 is specified for a :mimetype:`text/*` attachment. File Storage ~~~~~~~~~~~~ diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt index c64746443254..553e5156eb67 100644 --- a/docs/releases/1.5.txt +++ b/docs/releases/1.5.txt @@ -424,11 +424,11 @@ Non-form data in HTTP requests :attr:`request.POST ` will no longer include data posted via HTTP requests with non form-specific content-types in the header. In prior versions, data posted with content-types other than -``multipart/form-data`` or ``application/x-www-form-urlencoded`` would still -end up represented in the :attr:`request.POST ` -attribute. Developers wishing to access the raw POST data for these cases, -should use the :attr:`request.body ` attribute -instead. +:mimetype:`multipart/form-data` or +:mimetype:`application/x-www-form-urlencoded` would still end up represented in +the :attr:`request.POST ` attribute. Developers +wishing to access the raw POST data for these cases, should use the +:attr:`request.body ` attribute instead. :data:`~django.core.signals.request_finished` signal ---------------------------------------------------- diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index db3f6720ea66..98f6578bbabc 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -557,7 +557,9 @@ Email ~~~~~ * :func:`~django.core.mail.send_mail` now accepts an ``html_message`` - parameter for sending a multipart ``text/plain`` and ``text/html`` email. + parameter for sending a multipart :mimetype:`text/plain` and + :mimetype:`text/html` email. + * The SMTP :class:`~django.core.mail.backends.smtp.EmailBackend` now accepts a ``timeout`` parameter. diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index be45723bde4f..343c44084eb8 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -1287,8 +1287,8 @@ implementation details see :ref:`using-the-views`. default context data passed to the template. * ``html_email_template_name``: The full name of a template to use - for generating a ``text/html`` multipart email with the password reset - link. By default, HTML email is not sent. + for generating a :mimetype:`text/html` multipart email with the password + reset link. By default, HTML email is not sent. * ``extra_email_context``: A dictionary of context data that will be available in the email template. It can be used to override default diff --git a/docs/topics/email.txt b/docs/topics/email.txt index 46b1bb3ad592..6ea80e44ca63 100644 --- a/docs/topics/email.txt +++ b/docs/topics/email.txt @@ -341,15 +341,16 @@ The class has the following methods: message.attach('design.png', img_data, 'image/png') - If you specify a ``mimetype`` of ``message/rfc822``, it will also accept - :class:`django.core.mail.EmailMessage` and :py:class:`email.message.Message`. + If you specify a ``mimetype`` of :mimetype:`message/rfc822`, it will also + accept :class:`django.core.mail.EmailMessage` and + :py:class:`email.message.Message`. - For a ``mimetype`` starting with ``text/``, content is expected to be a - string. Binary data will be decoded using UTF-8, and if that fails, the - MIME type will be changed to ``application/octet-stream`` and the data will - be attached unchanged. + For a ``mimetype`` starting with :mimetype:`text/`, content is expected to + be a string. Binary data will be decoded using UTF-8, and if that fails, + the MIME type will be changed to :mimetype:`application/octet-stream` and + the data will be attached unchanged. - In addition, ``message/rfc822`` attachments will no longer be + In addition, :mimetype:`message/rfc822` attachments will no longer be base64-encoded in violation of :rfc:`2046#section-5.2.1`, which can cause issues with displaying the attachments in `Evolution`__ and `Thunderbird`__. @@ -363,7 +364,7 @@ The class has the following methods: message.attach_file('/images/weather_map.png') - For MIME types starting with ``text/``, binary data is handled as in + For MIME types starting with :mimetype:`text/`, binary data is handled as in ``attach()``. Sending alternative content types From fbdb032de266ba5f82e061ab204f6c622889d563 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Thu, 30 Apr 2020 11:12:05 +0100 Subject: [PATCH 0012/1251] Used :envvar: role and .. envvar:: directive in various docs. --- docs/faq/usage.txt | 6 ++-- docs/howto/deployment/wsgi/uwsgi.txt | 2 +- .../writing-code/coding-style.txt | 4 +-- .../contributing/writing-code/unit-tests.txt | 10 +++--- .../contributing/writing-documentation.txt | 4 +++ docs/intro/tutorial02.txt | 4 +-- docs/ref/checks.txt | 2 +- docs/ref/contrib/gis/geos.txt | 2 +- docs/ref/django-admin.txt | 29 ++++++++++------ docs/releases/1.2.txt | 6 ++-- docs/releases/1.4.txt | 2 +- docs/releases/2.2.1.txt | 3 +- docs/releases/3.0.1.txt | 2 +- docs/topics/async.txt | 4 ++- docs/topics/settings.txt | 34 +++++++++---------- 15 files changed, 65 insertions(+), 49 deletions(-) diff --git a/docs/faq/usage.txt b/docs/faq/usage.txt index 0145a580fd9a..f95ca1117433 100644 --- a/docs/faq/usage.txt +++ b/docs/faq/usage.txt @@ -2,12 +2,12 @@ FAQ: Using Django ================= -Why do I get an error about importing DJANGO_SETTINGS_MODULE? -============================================================= +Why do I get an error about importing :envvar:`DJANGO_SETTINGS_MODULE`? +======================================================================= Make sure that: -* The environment variable DJANGO_SETTINGS_MODULE is set to a +* The environment variable :envvar:`DJANGO_SETTINGS_MODULE` is set to a fully-qualified Python module (i.e. "mysite.settings"). * Said module is on ``sys.path`` (``import mysite.settings`` should work). diff --git a/docs/howto/deployment/wsgi/uwsgi.txt b/docs/howto/deployment/wsgi/uwsgi.txt index 561602ff3412..43cfdf3b9302 100644 --- a/docs/howto/deployment/wsgi/uwsgi.txt +++ b/docs/howto/deployment/wsgi/uwsgi.txt @@ -77,7 +77,7 @@ The Django-specific options here are: path -- i.e., the directory containing the ``mysite`` package. * ``module``: The WSGI module to use -- probably the ``mysite.wsgi`` module that :djadmin:`startproject` creates. -* ``env``: Should probably contain at least ``DJANGO_SETTINGS_MODULE``. +* ``env``: Should probably contain at least :envvar:`DJANGO_SETTINGS_MODULE`. * ``home``: Optional path to your project virtualenv. Example ini configuration file:: diff --git a/docs/internals/contributing/writing-code/coding-style.txt b/docs/internals/contributing/writing-code/coding-style.txt index 43db31501e10..6793dde79e6c 100644 --- a/docs/internals/contributing/writing-code/coding-style.txt +++ b/docs/internals/contributing/writing-code/coding-style.txt @@ -283,8 +283,8 @@ at the top level (i.e. evaluated when the module is imported). The explanation for this is as follows: Manual configuration of settings (i.e. not relying on the -``DJANGO_SETTINGS_MODULE`` environment variable) is allowed and possible as -follows:: +:envvar:`DJANGO_SETTINGS_MODULE` environment variable) is allowed and possible +as follows:: from django.conf import settings diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 21bdf00664e1..deaa5a0b1967 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -105,8 +105,8 @@ The remainder of this documentation shows commands for running tests without ``tox``, however, any option passed to ``runtests.py`` can also be passed to ``tox`` by prefixing the argument list with ``--``, as above. -Tox also respects the ``DJANGO_SETTINGS_MODULE`` environment variable, if set. -For example, the following is equivalent to the command above: +Tox also respects the :envvar:`DJANGO_SETTINGS_MODULE` environment variable, if +set. For example, the following is equivalent to the command above: .. code-block:: console @@ -156,7 +156,7 @@ those for ``contrib.postgres``, are specific to a particular database backend and will be skipped if run with a different backend. To run the tests with different settings, ensure that the module is on your -``PYTHONPATH`` and pass the module with ``--settings``. +:envvar:`PYTHONPATH` and pass the module with ``--settings``. The :setting:`DATABASES` setting in any test settings module needs to define two databases: @@ -495,8 +495,8 @@ test failures. You can adjust this behavior with the ``--parallel`` option: $ ./runtests.py basic --parallel=1 -You can also use the ``DJANGO_TEST_PROCESSES`` environment variable for this -purpose. +You can also use the :envvar:`DJANGO_TEST_PROCESSES` environment variable for +this purpose. Tips for writing tests ====================== diff --git a/docs/internals/contributing/writing-documentation.txt b/docs/internals/contributing/writing-documentation.txt index bd9d0e9495da..82f918f921ed 100644 --- a/docs/internals/contributing/writing-documentation.txt +++ b/docs/internals/contributing/writing-documentation.txt @@ -246,6 +246,10 @@ documentation: * Use :rst:role:`:mimetype:` to refer to a MIME Type unless the value is quoted for a code example. +* Use :rst:role:`:envvar:` to refer to an environment variable. You may + also need to define a reference to the documentation for that environment + variable using :rst:dir:`.. envvar:: `. + Django-specific markup ====================== diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index 42e3ccd11013..8ee3ec8159f2 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -378,8 +378,8 @@ API Django gives you. To invoke the Python shell, use this command: $ python manage.py shell We're using this instead of simply typing "python", because :file:`manage.py` -sets the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives Django -the Python import path to your :file:`mysite/settings.py` file. +sets the :envvar:`DJANGO_SETTINGS_MODULE` environment variable, which gives +Django the Python import path to your :file:`mysite/settings.py` file. Once you're in the shell, explore the :doc:`database API `:: diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 37a3a572c932..5d10482b0bb4 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -111,7 +111,7 @@ Asynchronous support The following checks verify your setup for :doc:`/topics/async`: -* **async.E001**: You should not set the ``DJANGO_ALLOW_ASYNC_UNSAFE`` +* **async.E001**: You should not set the :envvar:`DJANGO_ALLOW_ASYNC_UNSAFE` environment variable in deployment. This disables :ref:`async safety protection `. diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index cfb207288f77..74de7b255c54 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -32,7 +32,7 @@ features include: in Python using ``ctypes``. * Loosely-coupled to GeoDjango. For example, :class:`GEOSGeometry` objects may be used outside of a Django project/application. In other words, - no need to have ``DJANGO_SETTINGS_MODULE`` set or use a database, etc. + no need to have :envvar:`DJANGO_SETTINGS_MODULE` set or use a database, etc. * Mutability: :class:`GEOSGeometry` objects may be modified. * Cross-platform and tested; compatible with Windows, Linux, Solaris, and macOS platforms. diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index f48307fe2235..329cb72215ca 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -127,8 +127,8 @@ Activates some additional checks that are only relevant in a deployment setting. You can use this option in your local development environment, but since your local development settings module may not have many of your production settings, you will probably want to point the ``check`` command at a different settings -module, either by setting the ``DJANGO_SETTINGS_MODULE`` environment variable, -or by passing the ``--settings`` option:: +module, either by setting the :envvar:`DJANGO_SETTINGS_MODULE` environment +variable, or by passing the ``--settings`` option:: django-admin check --deploy --settings=production_settings @@ -940,8 +940,10 @@ more robust change detection, and a reduction in power usage. Django supports .. admonition:: Watchman timeout + .. envvar:: DJANGO_WATCHMAN_TIMEOUT + The default timeout of ``Watchman`` client is 5 seconds. You can change it - by setting the ``DJANGO_WATCHMAN_TIMEOUT`` environment variable. + by setting the :envvar:`DJANGO_WATCHMAN_TIMEOUT` environment variable. .. _Watchman: https://facebook.github.io/watchman/ .. _pywatchman: https://pypi.org/project/pywatchman/ @@ -1420,13 +1422,15 @@ Enables :ref:`SQL logging ` for failing tests. If .. django-admin-option:: --parallel [N] +.. envvar:: DJANGO_TEST_PROCESSES + Runs tests in separate parallel processes. Since modern processors have multiple cores, this allows running tests significantly faster. By default ``--parallel`` runs one process per core according to :func:`multiprocessing.cpu_count()`. You can adjust the number of processes either by providing it as the option's value, e.g. ``--parallel=4``, or by -setting the ``DJANGO_TEST_PROCESSES`` environment variable. +setting the :envvar:`DJANGO_TEST_PROCESSES` environment variable. Django distributes test cases — :class:`unittest.TestCase` subclasses — to subprocesses. If there are fewer test cases than configured processes, Django @@ -1599,6 +1603,8 @@ Example usage:: .. django-admin:: createsuperuser +.. envvar:: DJANGO_SUPERUSER_PASSWORD + This command is only available if Django's :doc:`authentication system ` (``django.contrib.auth``) is installed. @@ -1608,9 +1614,9 @@ programmatically generate superuser accounts for your site(s). When run interactively, this command will prompt for a password for the new superuser account. When run non-interactively, you can provide -a password by setting the ``DJANGO_SUPERUSER_PASSWORD`` environment variable. -Otherwise, no password will be set, and the superuser account will not be able -to log in until a password has been manually set for it. +a password by setting the :envvar:`DJANGO_SUPERUSER_PASSWORD` environment +variable. Otherwise, no password will be set, and the superuser account will +not be able to log in until a password has been manually set for it. In non-interactive mode, the :attr:`~django.contrib.auth.models.CustomUser.USERNAME_FIELD` and required @@ -1738,7 +1744,7 @@ allows for the following options: .. django-admin-option:: --pythonpath PYTHONPATH Adds the given filesystem path to the Python `import search path`_. If this -isn't provided, ``django-admin`` will use the ``PYTHONPATH`` environment +isn't provided, ``django-admin`` will use the :envvar:`PYTHONPATH` environment variable. This option is unnecessary in ``manage.py``, because it takes care of setting @@ -1754,7 +1760,8 @@ Example usage:: Specifies the settings module to use. The settings module should be in Python package syntax, e.g. ``mysite.settings``. If this isn't provided, -``django-admin`` will use the ``DJANGO_SETTINGS_MODULE`` environment variable. +``django-admin`` will use the :envvar:`DJANGO_SETTINGS_MODULE` environment +variable. This option is unnecessary in ``manage.py``, because it uses ``settings.py`` from the current project by default. @@ -1822,6 +1829,8 @@ Extra niceties Syntax coloring --------------- +.. envvar:: DJANGO_COLORS + The ``django-admin`` / ``manage.py`` commands will use pretty color-coded output if your terminal supports ANSI-colored output. It won't use the color codes if you're piping the command's output to @@ -1843,7 +1852,7 @@ ships with three color palettes: * ``nocolor``, which disables syntax highlighting. -You select a palette by setting a ``DJANGO_COLORS`` environment +You select a palette by setting a :envvar:`DJANGO_COLORS` environment variable to specify the palette you want to use. For example, to specify the ``light`` palette under a Unix or OS/X BASH shell, you would run the following at a command prompt:: diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt index d735d22f744d..0b761138e60e 100644 --- a/docs/releases/1.2.txt +++ b/docs/releases/1.2.txt @@ -321,9 +321,9 @@ and calculated values can be displayed alongside editable fields. Customizable syntax highlighting -------------------------------- -You can now use a ``DJANGO_COLORS`` environment variable to modify or disable -the colors used by ``django-admin.py`` to provide :ref:`syntax highlighting -`. +You can now use a :envvar:`DJANGO_COLORS` environment variable to modify or +disable the colors used by ``django-admin.py`` to provide :ref:`syntax +highlighting `. Syndication feeds as views -------------------------- diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index 9a802ac370eb..aa760cc4c94c 100644 --- a/docs/releases/1.4.txt +++ b/docs/releases/1.4.txt @@ -1257,7 +1257,7 @@ needed with the new ``manage.py`` and default project layout. This function was never documented or part of the public API, but it was widely recommended for use in setting up a "Django environment" for a user script. -These uses should be replaced by setting the ``DJANGO_SETTINGS_MODULE`` +These uses should be replaced by setting the :envvar:`DJANGO_SETTINGS_MODULE` environment variable or using :func:`django.conf.settings.configure`. ``django.core.management.execute_manager`` diff --git a/docs/releases/2.2.1.txt b/docs/releases/2.2.1.txt index 6438e7fc37e6..4eb4e18fe965 100644 --- a/docs/releases/2.2.1.txt +++ b/docs/releases/2.2.1.txt @@ -58,7 +58,8 @@ Bugfixes * Increased the default timeout when using ``Watchman`` to 5 seconds to prevent falling back to ``StatReloader`` on larger projects and made it customizable - via the ``DJANGO_WATCHMAN_TIMEOUT`` environment variable (:ticket:`30361`). + via the :envvar:`DJANGO_WATCHMAN_TIMEOUT` environment variable + (:ticket:`30361`). * Fixed a regression in Django 2.2 that caused a crash when migrating permissions for proxy models if the target permissions already existed. For diff --git a/docs/releases/3.0.1.txt b/docs/releases/3.0.1.txt index 1c325283049e..a0fb1f560c1e 100644 --- a/docs/releases/3.0.1.txt +++ b/docs/releases/3.0.1.txt @@ -28,7 +28,7 @@ Bugfixes * Fixed a regression in Django 3.0 by restoring the ability to use Django inside Jupyter and other environments that force an async context, by adding an option to disable :ref:`async-safety` mechanism with - ``DJANGO_ALLOW_ASYNC_UNSAFE`` environment variable (:ticket:`31056`). + :envvar:`DJANGO_ALLOW_ASYNC_UNSAFE` environment variable (:ticket:`31056`). * Fixed a regression in Django 3.0 where ``RegexPattern``, used by :func:`~django.urls.re_path`, returned positional arguments to be passed to diff --git a/docs/topics/async.txt b/docs/topics/async.txt index b3bd285afe17..3b3daeecce88 100644 --- a/docs/topics/async.txt +++ b/docs/topics/async.txt @@ -118,6 +118,8 @@ mode if you have asynchronous code in your project. Async safety ============ +.. envvar:: DJANGO_ALLOW_ASYNC_UNSAFE + Certain key parts of Django are not able to operate safely in an async environment, as they have global state that is not coroutine-aware. These parts of Django are classified as "async-unsafe", and are protected from execution in @@ -144,7 +146,7 @@ if the requirement is forced on you by an external environment, such as in a Jupyter_ notebook. If you are sure there is no chance of the code being run concurrently, and you *absolutely* need to run this sync code from an async context, then you can disable the warning by setting the -``DJANGO_ALLOW_ASYNC_UNSAFE`` environment variable to any value. +:envvar:`DJANGO_ALLOW_ASYNC_UNSAFE` environment variable to any value. .. warning:: diff --git a/docs/topics/settings.txt b/docs/topics/settings.txt index 7a420b6777a8..d09ba08b10e9 100644 --- a/docs/topics/settings.txt +++ b/docs/topics/settings.txt @@ -40,10 +40,10 @@ Designating the settings .. envvar:: DJANGO_SETTINGS_MODULE When you use Django, you have to tell it which settings you're using. Do this -by using an environment variable, ``DJANGO_SETTINGS_MODULE``. +by using an environment variable, :envvar:`DJANGO_SETTINGS_MODULE`. -The value of ``DJANGO_SETTINGS_MODULE`` should be in Python path syntax, e.g. -``mysite.settings``. Note that the settings module should be on the +The value of :envvar:`DJANGO_SETTINGS_MODULE` should be in Python path syntax, +e.g. ``mysite.settings``. Note that the settings module should be on the Python `import search path`_. .. _import search path: https://www.diveinto.org/python3/your-first-python-program.html#importsearchpath @@ -170,10 +170,10 @@ a convention. .. _settings-without-django-settings-module: -Using settings without setting ``DJANGO_SETTINGS_MODULE`` -========================================================= +Using settings without setting :envvar:`DJANGO_SETTINGS_MODULE` +=============================================================== -In some cases, you might want to bypass the ``DJANGO_SETTINGS_MODULE`` +In some cases, you might want to bypass the :envvar:`DJANGO_SETTINGS_MODULE` environment variable. For example, if you're using the template system by itself, you likely don't want to have to set up an environment variable pointing to a settings module. @@ -234,19 +234,19 @@ defaults, so you must specify a value for every possible setting that might be used in that code you are importing. Check in ``django.conf.settings.global_settings`` for the full list. -Either ``configure()`` or ``DJANGO_SETTINGS_MODULE`` is required ----------------------------------------------------------------- +Either ``configure()`` or :envvar:`DJANGO_SETTINGS_MODULE` is required +---------------------------------------------------------------------- -If you're not setting the ``DJANGO_SETTINGS_MODULE`` environment variable, you -*must* call ``configure()`` at some point before using any code that reads -settings. +If you're not setting the :envvar:`DJANGO_SETTINGS_MODULE` environment +variable, you *must* call ``configure()`` at some point before using any code +that reads settings. -If you don't set ``DJANGO_SETTINGS_MODULE`` and don't call ``configure()``, -Django will raise an ``ImportError`` exception the first time a setting -is accessed. +If you don't set :envvar:`DJANGO_SETTINGS_MODULE` and don't call +``configure()``, Django will raise an ``ImportError`` exception the first time +a setting is accessed. -If you set ``DJANGO_SETTINGS_MODULE``, access settings values somehow, *then* -call ``configure()``, Django will raise a ``RuntimeError`` indicating +If you set :envvar:`DJANGO_SETTINGS_MODULE`, access settings values somehow, +*then* call ``configure()``, Django will raise a ``RuntimeError`` indicating that settings have already been configured. There is a property for this purpose: @@ -262,7 +262,7 @@ Also, it's an error to call ``configure()`` more than once, or to call ``configure()`` after any setting has been accessed. It boils down to this: Use exactly one of either ``configure()`` or -``DJANGO_SETTINGS_MODULE``. Not both, and not neither. +:envvar:`DJANGO_SETTINGS_MODULE`. Not both, and not neither. Calling ``django.setup()`` is required for "standalone" Django usage -------------------------------------------------------------------- From d4c5ef3ebbdc160ba425d5073faddd8713da4ad2 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sun, 10 May 2020 22:30:03 +0200 Subject: [PATCH 0013/1251] Renamed PROJ.4 to PROJ. --- .../gis/db/backends/postgis/operations.py | 6 +++--- .../gis/db/backends/spatialite/operations.py | 4 ++-- django/contrib/gis/gdal/geometries.py | 2 +- django/contrib/gis/gdal/prototypes/srs.py | 2 +- django/contrib/gis/gdal/srs.py | 6 +++--- django/contrib/gis/geos/geometry.py | 2 +- docs/ref/contrib/gis/gdal.txt | 12 ++++++------ docs/ref/contrib/gis/geos.txt | 11 +++++------ docs/ref/contrib/gis/install/geolibs.txt | 16 ++++++++-------- docs/ref/contrib/gis/install/index.txt | 6 +++--- docs/ref/contrib/gis/install/spatialite.txt | 2 +- docs/ref/contrib/gis/layermapping.txt | 2 +- docs/ref/contrib/gis/tutorial.txt | 4 ++-- docs/releases/3.2.txt | 3 ++- tests/gis_tests/gdal_tests/test_srs.py | 2 +- tests/gis_tests/test_spatialrefsys.py | 16 ++++++++-------- 16 files changed, 48 insertions(+), 48 deletions(-) diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py index b59393909bcb..f81f5da1520b 100644 --- a/django/contrib/gis/db/backends/postgis/operations.py +++ b/django/contrib/gis/db/backends/postgis/operations.py @@ -314,7 +314,7 @@ def postgis_lib_version(self): return self._get_postgis_func('postgis_lib_version') def postgis_proj_version(self): - "Return the version of the PROJ.4 library used with PostGIS." + """Return the version of the PROJ library used with PostGIS.""" return self._get_postgis_func('postgis_proj_version') def postgis_version(self): @@ -335,7 +335,7 @@ def postgis_version_tuple(self): def proj_version_tuple(self): """ - Return the version of PROJ.4 used by PostGIS as a tuple of the + Return the version of PROJ used by PostGIS as a tuple of the major, minor, and subminor release numbers. """ proj_regex = re.compile(r'(\d+)\.(\d+)\.(\d+)') @@ -344,7 +344,7 @@ def proj_version_tuple(self): if m: return tuple(map(int, m.groups())) else: - raise Exception('Could not determine PROJ.4 version from PostGIS.') + raise Exception('Could not determine PROJ version from PostGIS.') def spatial_aggregate_name(self, agg_name): if agg_name == 'Extent3D': diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index 4d4d84aa6d82..332403162c25 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -159,8 +159,8 @@ def geos_version(self): "Return the version of GEOS used by SpatiaLite as a string." return self._get_spatialite_func('geos_version()') - def proj4_version(self): - "Return the version of the PROJ.4 library used by SpatiaLite." + def proj_version(self): + """Return the version of the PROJ library used by SpatiaLite.""" return self._get_spatialite_func('proj4_version()') def lwgeom_version(self): diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index 8ec5683b9c19..0aa1161243f3 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -383,7 +383,7 @@ def transform(self, coord_trans, clone=False): """ Transform this geometry to a different spatial reference system. May take a CoordTransform object, a SpatialReference object, string - WKT or PROJ.4, and/or an integer SRID. By default, return nothing + WKT or PROJ, and/or an integer SRID. By default, return nothing and transform the geometry in-place. However, if the `clone` keyword is set, return a transformed clone of this geometry. """ diff --git a/django/contrib/gis/gdal/prototypes/srs.py b/django/contrib/gis/gdal/prototypes/srs.py index 5d6a65c4fea4..5d080d8588be 100644 --- a/django/contrib/gis/gdal/prototypes/srs.py +++ b/django/contrib/gis/gdal/prototypes/srs.py @@ -57,7 +57,7 @@ def units_func(f): linear_units = units_func(lgdal.OSRGetLinearUnits) angular_units = units_func(lgdal.OSRGetAngularUnits) -# For exporting to WKT, PROJ.4, "Pretty" WKT, and XML. +# For exporting to WKT, PROJ, "Pretty" WKT, and XML. to_wkt = string_output(std_call('OSRExportToWkt'), [c_void_p, POINTER(c_char_p)], decoding='utf-8') to_proj = string_output(std_call('OSRExportToProj4'), [c_void_p, POINTER(c_char_p)], decoding='ascii') to_pretty_wkt = string_output( diff --git a/django/contrib/gis/gdal/srs.py b/django/contrib/gis/gdal/srs.py index d2e781e38175..fd6509600c8d 100644 --- a/django/contrib/gis/gdal/srs.py +++ b/django/contrib/gis/gdal/srs.py @@ -53,7 +53,7 @@ def __init__(self, srs_input='', srs_type='user', axis_order=None): """ Create a GDAL OSR Spatial Reference object from the given input. The input may be string of OGC Well Known Text (WKT), an integer - EPSG code, a PROJ.4 string, and/or a projection "well known" shorthand + EPSG code, a PROJ string, and/or a projection "well known" shorthand string (one of 'WGS84', 'WGS72', 'NAD27', 'NAD83'). """ if not isinstance(axis_order, (type(None), AxisOrder)): @@ -296,7 +296,7 @@ def import_epsg(self, epsg): capi.from_epsg(self.ptr, epsg) def import_proj(self, proj): - "Import the Spatial Reference from a PROJ.4 string." + """Import the Spatial Reference from a PROJ string.""" capi.from_proj(self.ptr, proj) def import_user_input(self, user_input): @@ -324,7 +324,7 @@ def pretty_wkt(self, simplify=0): @property def proj(self): - "Return the PROJ.4 representation for this Spatial Reference." + """Return the PROJ representation for this Spatial Reference.""" return capi.to_proj(self.ptr, byref(c_char_p())) @property diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index 8fb0117b3e22..e8702db251eb 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -447,7 +447,7 @@ def transform(self, ct, clone=False): """ Requires GDAL. Transform the geometry according to the given transformation object, which may be an integer SRID, and WKT or - PROJ.4 string. By default, transform the geometry in-place and return + PROJ string. By default, transform the geometry in-place and return nothing. However if the `clone` keyword is set, don't modify the geometry and return a transformed clone instead. """ diff --git a/docs/ref/contrib/gis/gdal.txt b/docs/ref/contrib/gis/gdal.txt index f022c89040e2..857d8d02f521 100644 --- a/docs/ref/contrib/gis/gdal.txt +++ b/docs/ref/contrib/gis/gdal.txt @@ -628,7 +628,7 @@ coordinate transformation:: Transforms this geometry to a different spatial reference system. May take a :class:`CoordTransform` object, a :class:`SpatialReference` object, or any other input accepted by :class:`SpatialReference` (including spatial - reference WKT and PROJ.4 strings, or an integer SRID). + reference WKT and PROJ strings, or an integer SRID). By default nothing is returned and the geometry is transformed in-place. However, if the ``clone`` keyword is set to ``True`` then a transformed @@ -881,7 +881,7 @@ Coordinate System Objects * OGC Well Known Text (WKT) (a string) * EPSG code (integer or string) - * PROJ.4 string + * PROJ string * A shorthand string for well-known standards (``'WGS84'``, ``'WGS72'``, ``'NAD27'``, ``'NAD83'``) @@ -890,8 +890,8 @@ Coordinate System Objects >>> wgs84 = SpatialReference('WGS84') # shorthand string >>> wgs84 = SpatialReference(4326) # EPSG code >>> wgs84 = SpatialReference('EPSG:4326') # EPSG string - >>> proj4 = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ' - >>> wgs84 = SpatialReference(proj4) # PROJ.4 string + >>> proj = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ' + >>> wgs84 = SpatialReference(proj) # PROJ string >>> wgs84 = SpatialReference("""GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563, @@ -967,7 +967,7 @@ Coordinate System Objects .. method:: import_proj(proj) - Import spatial reference from PROJ.4 string. + Import spatial reference from PROJ string. .. method:: import_user_input(user_input) @@ -1050,7 +1050,7 @@ Coordinate System Objects .. attribute:: proj - Returns the PROJ.4 representation for this spatial reference. + Returns the PROJ representation for this spatial reference. .. attribute:: proj4 diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index 74de7b255c54..446fb3810864 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -642,12 +642,11 @@ Other Properties & Methods Transforms the geometry according to the given coordinate transformation parameter (``ct``), which may be an integer SRID, spatial reference WKT - string, a PROJ.4 string, a - :class:`~django.contrib.gis.gdal.SpatialReference` object, or a - :class:`~django.contrib.gis.gdal.CoordTransform` object. By default, the - geometry is transformed in-place and nothing is returned. However if the - ``clone`` keyword is set, then the geometry is not modified and a - transformed clone of the geometry is returned instead. + string, a PROJ string, a :class:`~django.contrib.gis.gdal.SpatialReference` + object, or a :class:`~django.contrib.gis.gdal.CoordTransform` object. By + default, the geometry is transformed in-place and nothing is returned. + However if the ``clone`` keyword is set, then the geometry is not modified + and a transformed clone of the geometry is returned instead. .. note:: diff --git a/docs/ref/contrib/gis/install/geolibs.txt b/docs/ref/contrib/gis/install/geolibs.txt index 650577ac9dd3..1ba1ba06734e 100644 --- a/docs/ref/contrib/gis/install/geolibs.txt +++ b/docs/ref/contrib/gis/install/geolibs.txt @@ -9,7 +9,7 @@ geospatial libraries: Program Description Required Supported Versions ======================== ==================================== ================================ =================================== :doc:`GEOS <../geos>` Geometry Engine Open Source Yes 3.8, 3.7, 3.6, 3.5 -`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 6.3, 6.2, 6.1, 6.0, 5.x, 4.x +`PROJ`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 6.x, 5.x, 4.x :doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 3.1, 3.0, 2.4, 2.3, 2.2, 2.1, 2.0 :doc:`GeoIP <../geoip2>` IP-based geolocation library No 2 `PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.0, 2.5, 2.4, 2.3, 2.2 @@ -45,7 +45,7 @@ totally fine with GeoDjango. Your mileage may vary. independently of Django. In other words, no database or settings file required -- import them as normal from :mod:`django.contrib.gis`. -.. _PROJ.4: https://github.com/OSGeo/proj.4/wiki/ +.. _PROJ: https://proj.org/ __ https://postgis.net/ __ https://www.gaia-gis.it/gaia-sins/ @@ -146,13 +146,13 @@ See also :ref:`My logs are filled with GEOS-related errors `_ requires the ``null`` grid file only included in the extra datum shifting files. It is easier to install the shifting files now, then to have debug a diff --git a/docs/ref/contrib/gis/install/index.txt b/docs/ref/contrib/gis/install/index.txt index b6621f518c8e..df536f293765 100644 --- a/docs/ref/contrib/gis/install/index.txt +++ b/docs/ref/contrib/gis/install/index.txt @@ -58,10 +58,10 @@ supported versions, and any notes for each of the supported database backends: ================== ============================== ================== ========================================= Database Library Requirements Supported Versions Notes ================== ============================== ================== ========================================= -PostgreSQL GEOS, GDAL, PROJ.4, PostGIS 9.5+ Requires PostGIS. +PostgreSQL GEOS, GDAL, PROJ, PostGIS 9.5+ Requires PostGIS. MySQL GEOS, GDAL 5.6.1+ :ref:`Limited functionality `. Oracle GEOS, GDAL 12.2+ XE not supported. -SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.8.3+ Requires SpatiaLite 4.3+ +SQLite GEOS, GDAL, PROJ, SpatiaLite 3.8.3+ Requires SpatiaLite 4.3+ ================== ============================== ================== ========================================= See also `this comparison matrix`__ on the OSGeo Wiki for @@ -446,7 +446,7 @@ __ http://www.stickpeople.com/projects/python/win-psycopg/ OSGeo4W ~~~~~~~ -The `OSGeo4W installer`_ helps to install the PROJ.4, GDAL, and GEOS libraries +The `OSGeo4W installer`_ helps to install the PROJ, GDAL, and GEOS libraries required by GeoDjango. First, download the `OSGeo4W installer`_, and run it. Select :menuselection:`Express Web-GIS Install` and click next. In the 'Select Packages' list, ensure that GDAL is selected; MapServer and Apache are also diff --git a/docs/ref/contrib/gis/install/spatialite.txt b/docs/ref/contrib/gis/install/spatialite.txt index 9386168ce38e..a5a489eb3d6a 100644 --- a/docs/ref/contrib/gis/install/spatialite.txt +++ b/docs/ref/contrib/gis/install/spatialite.txt @@ -26,7 +26,7 @@ __ https://www.gaia-gis.it/gaia-sins/ Installing from source ====================== -:doc:`GEOS and PROJ.4` should be installed +:doc:`GEOS and PROJ` should be installed prior to building SpatiaLite. SQLite diff --git a/docs/ref/contrib/gis/layermapping.txt b/docs/ref/contrib/gis/layermapping.txt index 9d9fee988fae..cbce2aff59bd 100644 --- a/docs/ref/contrib/gis/layermapping.txt +++ b/docs/ref/contrib/gis/layermapping.txt @@ -114,7 +114,7 @@ Keyword Arguments ``source_srs`` Use this to specify the source SRS manually (for example, some shapefiles don't come with a ``'.prj'`` - file). An integer SRID, WKT or PROJ.4 strings, and + file). An integer SRID, WKT or PROJ strings, and :class:`django.contrib.gis.gdal.SpatialReference` objects are accepted. diff --git a/docs/ref/contrib/gis/tutorial.txt b/docs/ref/contrib/gis/tutorial.txt index 233ac1e8e78c..d69f5a7c7c6b 100644 --- a/docs/ref/contrib/gis/tutorial.txt +++ b/docs/ref/contrib/gis/tutorial.txt @@ -372,7 +372,7 @@ system associated with it. If it does, the ``srs`` attribute will return a SPHEROID["WGS_1984",6378137.0,298.257223563]], PRIMEM["Greenwich",0.0], UNIT["Degree",0.0174532925199433]] - >>> srs.proj4 # PROJ.4 representation + >>> srs.proj # PROJ representation '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ' This shapefile is in the popular WGS84 spatial reference @@ -751,7 +751,7 @@ This provides more context (including street and thoroughfare details) than available with the :class:`~django.contrib.gis.admin.GeoModelAdmin` (which uses the `Vector Map Level 0`_ WMS dataset hosted at `OSGeo`_). -The PROJ.4 datum shifting files must be installed (see the :ref:`PROJ.4 +The PROJ datum shifting files must be installed (see the :ref:`PROJ installation instructions ` for more details). If you meet this requirement, then substitute the ``OSMGeoAdmin`` option class diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt index 3950a70e7272..0e0bb4b3bd11 100644 --- a/docs/releases/3.2.txt +++ b/docs/releases/3.2.txt @@ -227,7 +227,8 @@ backends. Miscellaneous ------------- -* ... +* The undocumented ``SpatiaLiteOperations.proj4_version()`` method is renamed + to ``proj_version()``. .. _deprecated-features-3.2: diff --git a/tests/gis_tests/gdal_tests/test_srs.py b/tests/gis_tests/gdal_tests/test_srs.py index 27974c8b8025..1dfa05b1d046 100644 --- a/tests/gis_tests/gdal_tests/test_srs.py +++ b/tests/gis_tests/gdal_tests/test_srs.py @@ -181,7 +181,7 @@ def test03_get_wkt(self): ) def test04_proj(self): - "Test PROJ.4 import and export." + """PROJ import and export.""" proj_parts = [ '+proj=longlat', '+ellps=WGS84', '+towgs84=0,0,0,0,0,0,0', '+datum=WGS84', '+no_defs' ] diff --git a/tests/gis_tests/test_spatialrefsys.py b/tests/gis_tests/test_spatialrefsys.py index 6c5a1b921841..e4638baa3100 100644 --- a/tests/gis_tests/test_spatialrefsys.py +++ b/tests/gis_tests/test_spatialrefsys.py @@ -11,7 +11,7 @@ # Only the beginning, because there are differences depending on installed libs 'srtext': 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"', # +ellps=WGS84 has been removed in the 4326 proj string in proj-4.8 - 'proj4_re': r'\+proj=longlat (\+ellps=WGS84 )?(\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ?', + 'proj_re': r'\+proj=longlat (\+ellps=WGS84 )?(\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ?', 'spheroid': 'WGS 84', 'name': 'WGS 84', 'geographic': True, 'projected': False, 'spatialite': True, # From proj's "cs2cs -le" and Wikipedia (semi-minor only) @@ -37,9 +37,9 @@ 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",' 'DATUM["North_American_Datum_1983",SPHEROID["GRS 1980"' ), - 'proj4_re': r'\+proj=lcc (\+lat_1=30.28333333333333? |\+lat_2=28.38333333333333? |\+lat_0=27.83333333333333? |' - r'\+lon_0=-99 ){4}\+x_0=600000 \+y_0=4000000 (\+ellps=GRS80 )?' - r'(\+datum=NAD83 |\+towgs84=0,0,0,0,0,0,0 )?\+units=m \+no_defs ?', + 'proj_re': r'\+proj=lcc (\+lat_1=30.28333333333333? |\+lat_2=28.38333333333333? |\+lat_0=27.83333333333333? |' + r'\+lon_0=-99 ){4}\+x_0=600000 \+y_0=4000000 (\+ellps=GRS80 )?' + r'(\+datum=NAD83 |\+towgs84=0,0,0,0,0,0,0 )?\+units=m \+no_defs ?', 'spheroid': 'GRS 1980', 'name': 'NAD83 / Texas South Central', 'geographic': False, 'projected': True, 'spatialite': False, # From proj's "cs2cs -le" and Wikipedia (semi-minor only) @@ -74,10 +74,10 @@ def test_retrieve(self): self.assertEqual(sd['auth_srid'], srs.auth_srid) - # No proj.4 and different srtext on oracle backends :( + # No PROJ and different srtext on oracle backends :( if postgis: self.assertTrue(srs.wkt.startswith(sd['srtext'])) - self.assertRegex(srs.proj4text, sd['proj4_re']) + self.assertRegex(srs.proj4text, sd['proj_re']) def test_osr(self): """ @@ -90,14 +90,14 @@ def test_osr(self): self.assertEqual(sd['projected'], sr.projected) if not (spatialite and not sd['spatialite']): - # Can't get 'NAD83 / Texas South Central' from PROJ.4 string + # Can't get 'NAD83 / Texas South Central' from PROJ string # on SpatiaLite self.assertTrue(sr.name.startswith(sd['name'])) # Testing the SpatialReference object directly. if postgis or spatialite: srs = sr.srs - self.assertRegex(srs.proj4, sd['proj4_re']) + self.assertRegex(srs.proj, sd['proj_re']) self.assertTrue(srs.wkt.startswith(sd['srtext'])) def test_ellipsoid(self): From 49ae7ce50a874f8a04cd910882fb9571ff3a0d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 13 May 2020 11:07:15 +0000 Subject: [PATCH 0014/1251] Removed redundant assertions in fixtures tests. --- tests/fixtures/tests.py | 5 ----- tests/fixtures_model_package/tests.py | 1 - 2 files changed, 6 deletions(-) diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index cac3ccabc48d..d46bf65c976c 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -33,7 +33,6 @@ class TestCaseFixtureLoadingTests(TestCase): def test_class_fixtures(self): "Test case has installed 3 fixture objects" - self.assertEqual(Article.objects.count(), 3) self.assertQuerysetEqual(Article.objects.all(), [ '', '', @@ -721,7 +720,6 @@ def test_loading_stdin(self): with mock.patch('django.core.management.commands.loaddata.sys.stdin', open(fixture_json)): management.call_command('loaddata', '--format=json', '-', verbosity=0) - self.assertEqual(Article.objects.count(), 2) self.assertQuerysetEqual(Article.objects.all(), [ '', '', @@ -729,7 +727,6 @@ def test_loading_stdin(self): with mock.patch('django.core.management.commands.loaddata.sys.stdin', open(fixture_xml)): management.call_command('loaddata', '--format=xml', '-', verbosity=0) - self.assertEqual(Article.objects.count(), 3) self.assertQuerysetEqual(Article.objects.all(), [ '', '', @@ -810,7 +807,6 @@ def test_format_discovery(self): class ForwardReferenceTests(DumpDataAssertMixin, TestCase): def test_forward_reference_fk(self): management.call_command('loaddata', 'forward_reference_fk.json', verbosity=0) - self.assertEqual(NaturalKeyThing.objects.count(), 2) t1, t2 = NaturalKeyThing.objects.all() self.assertEqual(t1.other_thing, t2) self.assertEqual(t2.other_thing, t1) @@ -828,7 +824,6 @@ def test_forward_reference_fk_natural_key(self): 'forward_reference_fk_natural_key.json', verbosity=0, ) - self.assertEqual(NaturalKeyThing.objects.count(), 2) t1, t2 = NaturalKeyThing.objects.all() self.assertEqual(t1.other_thing, t2) self.assertEqual(t2.other_thing, t1) diff --git a/tests/fixtures_model_package/tests.py b/tests/fixtures_model_package/tests.py index 56d833b9f9cf..78afed1b9041 100644 --- a/tests/fixtures_model_package/tests.py +++ b/tests/fixtures_model_package/tests.py @@ -10,7 +10,6 @@ class SampleTestCase(TestCase): def test_class_fixtures(self): "Test cases can load fixture objects into models defined in packages" - self.assertEqual(Article.objects.count(), 3) self.assertQuerysetEqual( Article.objects.all(), [ "Django conquers world!", From 01a381cc17e6747e1d9e7b95a39e885029fd2a81 Mon Sep 17 00:00:00 2001 From: Hasan Ramezani Date: Wed, 13 May 2020 14:44:10 +0200 Subject: [PATCH 0015/1251] Fixed #31580 -- Added error messages on distinct() following union(), intersection(), and difference(). --- django/db/models/query.py | 1 + tests/queries/test_qs_combinators.py | 1 + 2 files changed, 2 insertions(+) diff --git a/django/db/models/query.py b/django/db/models/query.py index e0eeccefa68e..5c70229263cc 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1138,6 +1138,7 @@ def distinct(self, *field_names): """ Return a new QuerySet instance that will select only distinct results. """ + self._not_support_combined_queries('distinct') assert not self.query.is_sliced, \ "Cannot create distinct fields once a slice has been taken." obj = self._chain() diff --git a/tests/queries/test_qs_combinators.py b/tests/queries/test_qs_combinators.py index 1d159e1fed67..d2e7d2b80d47 100644 --- a/tests/queries/test_qs_combinators.py +++ b/tests/queries/test_qs_combinators.py @@ -272,6 +272,7 @@ def test_unsupported_operations_on_combined_qs(self): 'annotate', 'defer', 'delete', + 'distinct', 'exclude', 'extra', 'filter', From 18eb852874a073001cb509f64002b6d82bdc760b Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Wed, 13 May 2020 15:07:21 +0200 Subject: [PATCH 0016/1251] Fixed #31576 -- Fixed selenium tests with headless mode. Horizontal scrollbar doesn't appear with the headless mode on small windows, that's why window.scrollTo() is not an option for these tests. Tests changed after adding a navigation sidebar in 46fe506445666d8097945f0c1e8be11cfd644b28. --- tests/admin_widgets/tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index 34166f986c87..7241ea955470 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -880,6 +880,7 @@ def test_calendar_show_date_from_input(self): The calendar shows the date from the input field for every locale supported by Django. """ + self.selenium.set_window_size(1024, 768) self.admin_login(username='super', password='secret', login_url='/') # Enter test data @@ -1142,6 +1143,7 @@ def execute_basic_operations(self, mode, field_name): self.assertEqual(self.selenium.current_url, original_url) def test_basic(self): + self.selenium.set_window_size(1024, 768) self.school.students.set([self.lisa, self.peter]) self.school.alumni.set([self.lisa, self.peter]) @@ -1166,6 +1168,7 @@ def test_filter(self): """ from selenium.webdriver.common.keys import Keys + self.selenium.set_window_size(1024, 768) self.school.students.set([self.lisa, self.peter]) self.school.alumni.set([self.lisa, self.peter]) From 0a627dbe73dee6f5833221b6c67ecce7ebb2b223 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Wed, 13 May 2020 12:07:14 -0700 Subject: [PATCH 0017/1251] Removed unused Downcoder.chars. Unused -- other than as a local variable -- since its introduction in 953badbea5a04159adbfa970f5805c0232b6a401 --- django/contrib/admin/static/admin/js/urlify.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/django/contrib/admin/static/admin/js/urlify.js b/django/contrib/admin/static/admin/js/urlify.js index 7faa65912c1e..cf79777e7852 100644 --- a/django/contrib/admin/static/admin/js/urlify.js +++ b/django/contrib/admin/static/admin/js/urlify.js @@ -134,8 +134,7 @@ for (const lookup of ALL_DOWNCODE_MAPS) { Object.assign(Downcoder.map, lookup); } - Downcoder.chars = Object.keys(Downcoder.map); - Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g'); + Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g'); } }; From 50798d43898c7d46926a4292f86fdf3859a433da Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Thu, 14 May 2020 06:22:54 +0200 Subject: [PATCH 0018/1251] Added stub release notes for 2.2.13. --- docs/releases/2.2.13.txt | 12 ++++++++++++ docs/releases/index.txt | 1 + 2 files changed, 13 insertions(+) create mode 100644 docs/releases/2.2.13.txt diff --git a/docs/releases/2.2.13.txt b/docs/releases/2.2.13.txt new file mode 100644 index 000000000000..7fb6405ed5d7 --- /dev/null +++ b/docs/releases/2.2.13.txt @@ -0,0 +1,12 @@ +=========================== +Django 2.2.13 release notes +=========================== + +*Expected June 1, 2020* + +Django 2.2.13 fixes a bug in 2.2.12. + +Bugfixes +======== + +* ... diff --git a/docs/releases/index.txt b/docs/releases/index.txt index 4e337dcf7d60..20c1318d9563 100644 --- a/docs/releases/index.txt +++ b/docs/releases/index.txt @@ -53,6 +53,7 @@ versions of the documentation contain the release notes for any later releases. .. toctree:: :maxdepth: 1 + 2.2.13 2.2.12 2.2.11 2.2.10 From e536fa5ce1f2249d171c5890751aea58e51b3849 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Thu, 14 May 2020 06:33:00 +0200 Subject: [PATCH 0019/1251] Fixed #31579 -- Dropped support for PostgreSQL 9.5 and PostGIS 2.2. --- django/contrib/gis/db/backends/postgis/operations.py | 2 +- django/contrib/postgres/indexes.py | 4 ---- django/db/backends/postgresql/features.py | 6 ------ docs/ref/contrib/gis/install/geolibs.txt | 3 +-- docs/ref/contrib/gis/install/index.txt | 2 +- docs/ref/databases.txt | 2 +- docs/releases/3.2.txt | 11 +++++++++++ .../migrations/0001_setup_extensions.py | 8 ++------ tests/postgres_tests/test_indexes.py | 12 ------------ tests/postgres_tests/test_search.py | 3 --- 10 files changed, 17 insertions(+), 36 deletions(-) diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py index f81f5da1520b..e9bcfc8a30e0 100644 --- a/django/contrib/gis/db/backends/postgis/operations.py +++ b/django/contrib/gis/db/backends/postgis/operations.py @@ -180,7 +180,7 @@ def spatial_version(self): raise ImproperlyConfigured( 'Cannot determine PostGIS version for database "%s" ' 'using command "SELECT postgis_lib_version()". ' - 'GeoDjango requires at least PostGIS version 2.2. ' + 'GeoDjango requires at least PostGIS version 2.3. ' 'Was the database created from a spatial database ' 'template?' % self.connection.settings_dict['NAME'] ) diff --git a/django/contrib/postgres/indexes.py b/django/contrib/postgres/indexes.py index a5ffe9443128..91286046e43d 100644 --- a/django/contrib/postgres/indexes.py +++ b/django/contrib/postgres/indexes.py @@ -68,10 +68,6 @@ def deconstruct(self): kwargs['columns'] = self.columns return path, args, kwargs - def check_supported(self, schema_editor): - if not schema_editor.connection.features.has_bloom_index: - raise NotSupportedError('Bloom indexes require PostgreSQL 9.6+.') - def get_with_params(self): with_params = [] if self.length is not None: diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py index 00a8009cf2cd..80cee8e8da9d 100644 --- a/django/db/backends/postgresql/features.py +++ b/django/db/backends/postgresql/features.py @@ -59,10 +59,6 @@ class DatabaseFeatures(BaseDatabaseFeatures): validates_explain_options = False # A query will error on invalid options. supports_deferrable_unique_constraints = True - @cached_property - def is_postgresql_9_6(self): - return self.connection.pg_version >= 90600 - @cached_property def is_postgresql_10(self): return self.connection.pg_version >= 100000 @@ -75,8 +71,6 @@ def is_postgresql_11(self): def is_postgresql_12(self): return self.connection.pg_version >= 120000 - has_bloom_index = property(operator.attrgetter('is_postgresql_9_6')) has_brin_autosummarize = property(operator.attrgetter('is_postgresql_10')) - has_phraseto_tsquery = property(operator.attrgetter('is_postgresql_9_6')) has_websearch_to_tsquery = property(operator.attrgetter('is_postgresql_11')) supports_table_partitions = property(operator.attrgetter('is_postgresql_10')) diff --git a/docs/ref/contrib/gis/install/geolibs.txt b/docs/ref/contrib/gis/install/geolibs.txt index 1ba1ba06734e..74f17d886a95 100644 --- a/docs/ref/contrib/gis/install/geolibs.txt +++ b/docs/ref/contrib/gis/install/geolibs.txt @@ -12,7 +12,7 @@ Program Description Required `PROJ`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 6.x, 5.x, 4.x :doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 3.1, 3.0, 2.4, 2.3, 2.2, 2.1, 2.0 :doc:`GeoIP <../geoip2>` IP-based geolocation library No 2 -`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.0, 2.5, 2.4, 2.3, 2.2 +`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.0, 2.5, 2.4, 2.3 `SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.3 ======================== ==================================== ================================ =================================== @@ -32,7 +32,6 @@ totally fine with GeoDjango. Your mileage may vary. GDAL 2.4.0 2018-12 GDAL 3.0.0 2019-05 GDAL 3.1.0 2020-05-07 - PostGIS 2.2.0 2015-10-17 PostGIS 2.3.0 2016-09-26 PostGIS 2.4.0 2017-09-30 PostGIS 2.5.0 2018-09-23 diff --git a/docs/ref/contrib/gis/install/index.txt b/docs/ref/contrib/gis/install/index.txt index df536f293765..5242425aaa72 100644 --- a/docs/ref/contrib/gis/install/index.txt +++ b/docs/ref/contrib/gis/install/index.txt @@ -58,7 +58,7 @@ supported versions, and any notes for each of the supported database backends: ================== ============================== ================== ========================================= Database Library Requirements Supported Versions Notes ================== ============================== ================== ========================================= -PostgreSQL GEOS, GDAL, PROJ, PostGIS 9.5+ Requires PostGIS. +PostgreSQL GEOS, GDAL, PROJ, PostGIS 9.6+ Requires PostGIS. MySQL GEOS, GDAL 5.6.1+ :ref:`Limited functionality `. Oracle GEOS, GDAL 12.2+ XE not supported. SQLite GEOS, GDAL, PROJ, SpatiaLite 3.8.3+ Requires SpatiaLite 4.3+ diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index ef384f14e922..d788f2f67707 100644 --- a/docs/ref/databases.txt +++ b/docs/ref/databases.txt @@ -103,7 +103,7 @@ below for information on how to set up your database correctly. PostgreSQL notes ================ -Django supports PostgreSQL 9.5 and higher. `psycopg2`_ 2.5.4 or higher is +Django supports PostgreSQL 9.6 and higher. `psycopg2`_ 2.5.4 or higher is required, though the latest release is recommended. .. _psycopg2: https://www.psycopg.org/ diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt index 0e0bb4b3bd11..9b485b9e285d 100644 --- a/docs/releases/3.2.txt +++ b/docs/releases/3.2.txt @@ -224,6 +224,17 @@ backends. * ... +:mod:`django.contrib.gis` +------------------------- + +* Support for PostGIS 2.2 is removed. + +Dropped support for PostgreSQL 9.5 +---------------------------------- + +Upstream support for PostgreSQL 9.5 ends in February 2021. Django 3.2 supports +PostgreSQL 9.6 and higher. + Miscellaneous ------------- diff --git a/tests/postgres_tests/migrations/0001_setup_extensions.py b/tests/postgres_tests/migrations/0001_setup_extensions.py index d0a21791ba8a..5064f7ff99e4 100644 --- a/tests/postgres_tests/migrations/0001_setup_extensions.py +++ b/tests/postgres_tests/migrations/0001_setup_extensions.py @@ -1,6 +1,6 @@ from unittest import mock -from django.db import connection, migrations +from django.db import migrations try: from django.contrib.postgres.operations import ( @@ -23,11 +23,7 @@ class Migration(migrations.Migration): operations = [ - ( - BloomExtension() - if getattr(connection.features, 'has_bloom_index', False) - else mock.Mock() - ), + BloomExtension(), BtreeGinExtension(), BtreeGistExtension(), CITextExtension(), diff --git a/tests/postgres_tests/test_indexes.py b/tests/postgres_tests/test_indexes.py index acdf1f477178..0440beda5d07 100644 --- a/tests/postgres_tests/test_indexes.py +++ b/tests/postgres_tests/test_indexes.py @@ -260,7 +260,6 @@ def test_gin_parameters(self): editor.remove_index(IntegerArrayModel, index) self.assertNotIn(index_name, self.get_constraints(IntegerArrayModel._meta.db_table)) - @skipUnlessDBFeature('has_bloom_index') def test_bloom_index(self): index_name = 'char_field_model_field_bloom' index = BloomIndex(fields=['field'], name=index_name) @@ -272,7 +271,6 @@ def test_bloom_index(self): editor.remove_index(CharFieldModel, index) self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table)) - @skipUnlessDBFeature('has_bloom_index') def test_bloom_parameters(self): index_name = 'char_field_model_field_bloom_params' index = BloomIndex(fields=['field'], name=index_name, length=512, columns=[3]) @@ -285,16 +283,6 @@ def test_bloom_parameters(self): editor.remove_index(CharFieldModel, index) self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table)) - def test_bloom_index_not_supported(self): - index_name = 'bloom_index_exception' - index = BloomIndex(fields=['field'], name=index_name) - msg = 'Bloom indexes require PostgreSQL 9.6+.' - with self.assertRaisesMessage(NotSupportedError, msg): - with mock.patch('django.db.backends.postgresql.features.DatabaseFeatures.has_bloom_index', False): - with connection.schema_editor() as editor: - editor.add_index(CharFieldModel, index) - self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table)) - def test_brin_index(self): index_name = 'char_field_model_field_brin' index = BrinIndex(fields=['field'], name=index_name, pages_per_range=4) diff --git a/tests/postgres_tests/test_search.py b/tests/postgres_tests/test_search.py index f6c3031bd4d5..65ee9ffa2090 100644 --- a/tests/postgres_tests/test_search.py +++ b/tests/postgres_tests/test_search.py @@ -195,7 +195,6 @@ def test_search_with_non_text(self): ).filter(search=str(self.crowd.id)) self.assertSequenceEqual(searched, [self.crowd]) - @skipUnlessDBFeature('has_phraseto_tsquery') def test_phrase_search(self): line_qs = Line.objects.annotate(search=SearchVector('dialogue')) searched = line_qs.filter(search=SearchQuery('burned body his away', search_type='phrase')) @@ -203,7 +202,6 @@ def test_phrase_search(self): searched = line_qs.filter(search=SearchQuery('his body burned away', search_type='phrase')) self.assertSequenceEqual(searched, [self.verse1]) - @skipUnlessDBFeature('has_phraseto_tsquery') def test_phrase_search_with_config(self): line_qs = Line.objects.annotate( search=SearchVector('scene__setting', 'dialogue', config='french'), @@ -386,7 +384,6 @@ def test_combined_configs(self): ) self.assertSequenceEqual(searched, [self.verse2]) - @skipUnlessDBFeature('has_phraseto_tsquery') def test_combine_raw_phrase(self): searched = Line.objects.filter( dialogue__search=( From 42c08ee46539ef44f8658ebb1cbefb408e0d03fe Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Wed, 13 May 2020 23:38:29 -0400 Subject: [PATCH 0020/1251] Fixed #31566 -- Fixed aliases crash when chaining values()/values_list() after annotate() with aggregations and subqueries. Subquery annotation references must be resolved if they are excluded from the GROUP BY clause by a following .values() call. Regression in fb3f034f1c63160c0ff13c609acd01c18be12f80. Thanks Makina Corpus for the report. --- django/db/models/sql/query.py | 9 +++++++++ docs/releases/3.0.7.txt | 4 ++++ tests/annotations/tests.py | 20 ++++++++++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index bb230647ebe9..f8e146b8deec 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -2155,6 +2155,15 @@ def set_values(self, fields): # SELECT clause which is about to be cleared. self.set_group_by(allow_aliases=False) self.clear_select_fields() + elif self.group_by: + # Resolve GROUP BY annotation references if they are not part of + # the selected fields anymore. + group_by = [] + for expr in self.group_by: + if isinstance(expr, Ref) and expr.refs not in field_names: + expr = self.annotations[expr.refs] + group_by.append(expr) + self.group_by = tuple(group_by) self.values_select = tuple(field_names) self.add_fields(field_names, True) diff --git a/docs/releases/3.0.7.txt b/docs/releases/3.0.7.txt index 9fc71d9aa28b..5457e59b3d98 100644 --- a/docs/releases/3.0.7.txt +++ b/docs/releases/3.0.7.txt @@ -11,3 +11,7 @@ Bugfixes * Fixed a regression in Django 3.0 by restoring the ability to use field lookups in ``Meta.ordering`` (:ticket:`31538`). + +* Fixed a regression in Django 3.0 where ``QuerySet.values()`` and + ``values_list()`` crashed if a queryset contained an aggregation and a + subquery annotation (:ticket:`31566`). diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py index db4413564cd3..dad34e03eba6 100644 --- a/tests/annotations/tests.py +++ b/tests/annotations/tests.py @@ -1,10 +1,13 @@ import datetime from decimal import Decimal +from unittest import skipIf from django.core.exceptions import FieldDoesNotExist, FieldError +from django.db import connection from django.db.models import ( - BooleanField, CharField, Count, DateTimeField, ExpressionWrapper, F, Func, - IntegerField, NullBooleanField, OuterRef, Q, Subquery, Sum, Value, + BooleanField, CharField, Count, DateTimeField, Exists, ExpressionWrapper, + F, Func, IntegerField, Max, NullBooleanField, OuterRef, Q, Subquery, Sum, + Value, ) from django.db.models.expressions import RawSQL from django.db.models.functions import Length, Lower @@ -619,3 +622,16 @@ def test_annotation_filter_with_subquery(self): total_books=Subquery(long_books_qs, output_field=IntegerField()), ).values('name') self.assertCountEqual(publisher_books_qs, [{'name': 'Sams'}, {'name': 'Morgan Kaufmann'}]) + + @skipIf(connection.vendor == 'oracle', 'See https://code.djangoproject.com/ticket/31584') + def test_annotation_exists_aggregate_values_chaining(self): + qs = Book.objects.values('publisher').annotate( + has_authors=Exists(Book.authors.through.objects.filter(book=OuterRef('pk'))), + max_pubdate=Max('pubdate'), + ).values_list('max_pubdate', flat=True).order_by('max_pubdate') + self.assertCountEqual(qs, [ + datetime.date(1991, 10, 15), + datetime.date(2008, 3, 3), + datetime.date(2008, 6, 23), + datetime.date(2008, 11, 3), + ]) From adfbf653dc1c1d0e0dacc4ed46602d22ba28b004 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Thu, 14 May 2020 00:14:48 -0400 Subject: [PATCH 0021/1251] Fixed #31568 -- Fixed alias reference when aggregating over multiple subqueries. 691def10a0197d83d2d108bd9043b0916d0f09b4 made all Subquery() instances equal to each other which broke aggregation subquery pushdown which relied on object equality to determine which alias it should select. Subquery.__eq__() will be fixed in an another commit but Query.rewrite_cols() should haved used object identity from the start. Refs #30727, #30188. Thanks Makina Corpus for the report. --- django/db/models/sql/query.py | 2 +- docs/releases/3.0.7.txt | 3 +++ tests/aggregation/test_filter_argument.py | 23 ++++++++++++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index f8e146b8deec..375e22c4de1c 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -390,7 +390,7 @@ def rewrite_cols(self, annotation, col_cnt): else: # Reuse aliases of expressions already selected in subquery. for col_alias, selected_annotation in self.annotation_select.items(): - if selected_annotation == expr: + if selected_annotation is expr: new_expr = Ref(col_alias, expr) break else: diff --git a/docs/releases/3.0.7.txt b/docs/releases/3.0.7.txt index 5457e59b3d98..0f1188724a8d 100644 --- a/docs/releases/3.0.7.txt +++ b/docs/releases/3.0.7.txt @@ -15,3 +15,6 @@ Bugfixes * Fixed a regression in Django 3.0 where ``QuerySet.values()`` and ``values_list()`` crashed if a queryset contained an aggregation and a subquery annotation (:ticket:`31566`). + +* Fixed a regression in Django 3.0 where aggregates used wrong annotations when + a queryset has multiple subqueries annotations (:ticket:`31568`). diff --git a/tests/aggregation/test_filter_argument.py b/tests/aggregation/test_filter_argument.py index 0c8829efdf68..650cb8e46061 100644 --- a/tests/aggregation/test_filter_argument.py +++ b/tests/aggregation/test_filter_argument.py @@ -2,7 +2,8 @@ from decimal import Decimal from django.db.models import ( - Avg, Case, Count, F, OuterRef, Q, StdDev, Subquery, Sum, Variance, When, + Avg, Case, Count, Exists, F, Max, OuterRef, Q, StdDev, Subquery, Sum, + Variance, When, ) from django.test import TestCase from django.test.utils import Approximate @@ -120,3 +121,23 @@ def test_filtered_aggregate_ref_subquery_annotation(self): cnt=Count('pk', filter=Q(earliest_book_year=2008)), ) self.assertEqual(aggs['cnt'], 2) + + def test_filtered_aggregate_ref_multiple_subquery_annotation(self): + aggregate = Book.objects.values('publisher').annotate( + has_authors=Exists( + Book.authors.through.objects.filter(book=OuterRef('pk')), + ), + authors_have_other_books=Exists( + Book.objects.filter( + authors__in=Author.objects.filter( + book_contact_set=OuterRef(OuterRef('pk')), + ) + ).exclude(pk=OuterRef('pk')), + ), + ).aggregate( + max_rating=Max( + 'rating', + filter=Q(has_authors=True, authors_have_other_books=False), + ) + ) + self.assertEqual(aggregate, {'max_rating': 4.5}) From e341bed606d8ab2864838795276692cf86b08687 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Thu, 14 May 2020 10:25:06 +0200 Subject: [PATCH 0022/1251] Refs #31034 -- Documented admin requires django.template.context_processors.request. Required since d24ba1be7a53a113d19e2860c03aff9922efec24. Co-authored-by: Carlton Gibson --- docs/ref/contrib/admin/index.txt | 9 ++++++++- docs/releases/3.1.txt | 5 +++++ docs/spelling_wordlist | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 420dac182b97..085beb451861 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -34,11 +34,18 @@ If you're not using the default project template, here are the requirements: #. Configure a :class:`~django.template.backends.django.DjangoTemplates` backend in your :setting:`TEMPLATES` setting with - ``django.contrib.auth.context_processors.auth`` and + ``django.contrib.auth.context_processors.auth``, + ``django.contrib.messages.context_processors.request``, and ``django.contrib.messages.context_processors.messages`` in the ``'context_processors'`` option of :setting:`OPTIONS `. + .. versionchanged:: 3.1 + + ``django.contrib.messages.context_processors.request`` was added as a + requirement in the ``'context_processors'`` option to support the new + :attr:`.AdminSite.enable_nav_sidebar`. + #. If you've customized the :setting:`MIDDLEWARE` setting, :class:`django.contrib.auth.middleware.AuthenticationMiddleware` and :class:`django.contrib.messages.middleware.MessageMiddleware` must be diff --git a/docs/releases/3.1.txt b/docs/releases/3.1.txt index 268e92433ce2..1b2c1fee34a5 100644 --- a/docs/releases/3.1.txt +++ b/docs/releases/3.1.txt @@ -96,6 +96,11 @@ Minor features enabled by default but can be disabled by using a custom ``AdminSite`` and setting :attr:`.AdminSite.enable_nav_sidebar` to ``False``. + Rendering the sidebar requires access to the current request in order to set + CSS and ARIA role affordances. This requires using + ``'django.template.context_processors.request'`` in the + ``'context_processors'`` option of :setting:`OPTIONS `. + * ``XRegExp`` is upgraded from version 2.0.0 to 3.2.0. * jQuery is upgraded from version 3.4.1 to 3.5.1. diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist index cb1d8691473e..61e47022754c 100644 --- a/docs/spelling_wordlist +++ b/docs/spelling_wordlist @@ -6,6 +6,7 @@ admin admindocs admins affine +affordances aggregator Ai Alchin From d522b51c401429c169d88742178a9b3777903d9e Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Thu, 14 May 2020 10:27:35 +0200 Subject: [PATCH 0023/1251] Fixed #31575 -- Added system check for admin sidebar request context processor dependency. Co-authored-by: Carlton Gibson --- django/contrib/admin/checks.py | 10 ++++++++++ docs/ref/checks.txt | 3 +++ tests/admin_checks/tests.py | 12 +++++++++++- tests/admin_scripts/tests.py | 1 + tests/admin_views/test_nav_sidebar.py | 26 ++++++++++++++++++++++++-- tests/admin_views/tests.py | 2 ++ tests/auth_tests/settings.py | 1 + 7 files changed, 52 insertions(+), 3 deletions(-) diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py index 533e66a19f3d..5e4b785c3363 100644 --- a/django/contrib/admin/checks.py +++ b/django/contrib/admin/checks.py @@ -59,6 +59,7 @@ def check_dependencies(**kwargs): """ Check that the admin's dependencies are correctly installed. """ + from django.contrib.admin.sites import all_sites if not apps.is_installed('django.contrib.admin'): return [] errors = [] @@ -105,6 +106,15 @@ def check_dependencies(**kwargs): "the admin application.", id='admin.E404', )) + sidebar_enabled = any(site.enable_nav_sidebar for site in all_sites) + if (sidebar_enabled and 'django.template.context_processors.request' + not in django_templates_instance.context_processors): + errors.append(checks.Warning( + "'django.template.context_processors.request' must be enabled " + "in DjangoTemplates (TEMPLATES) in order to use the admin " + "navigation sidebar.", + id='admin.W411', + )) if not _contains_subclass('django.contrib.auth.middleware.AuthenticationMiddleware', settings.MIDDLEWARE): errors.append(checks.Error( diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 5d10482b0bb4..1259a4a28512 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -734,6 +734,9 @@ The following checks are performed on the default must be in :setting:`MIDDLEWARE` in order to use the admin application. * **admin.E410**: :class:`django.contrib.sessions.middleware.SessionMiddleware` must be in :setting:`MIDDLEWARE` in order to use the admin application. +* **admin.W411**: ``django.template.context_processors.request`` must be + enabled in :class:`~django.template.backends.django.DjangoTemplates` + (:setting:`TEMPLATES`) in order to use the admin navigation sidebar. ``auth`` -------- diff --git a/tests/admin_checks/tests.py b/tests/admin_checks/tests.py index 2a9643cd95d1..52f2188c9fb5 100644 --- a/tests/admin_checks/tests.py +++ b/tests/admin_checks/tests.py @@ -134,6 +134,12 @@ def test_context_processor_dependencies(self): "be enabled in DjangoTemplates (TEMPLATES) in order to use " "the admin application.", id='admin.E404', + ), + checks.Warning( + "'django.template.context_processors.request' must be enabled " + "in DjangoTemplates (TEMPLATES) in order to use the admin " + "navigation sidebar.", + id='admin.W411', ) ] self.assertEqual(admin.checks.check_dependencies(), expected) @@ -150,7 +156,10 @@ def test_context_processor_dependencies(self): 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { - 'context_processors': ['django.contrib.messages.context_processors.messages'], + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.messages.context_processors.messages', + ], }, }], ) @@ -177,6 +186,7 @@ def test_context_processor_dependencies_model_backend_subclass(self): 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ + 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index d0af160c5fcb..fac1c99c9749 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -1124,6 +1124,7 @@ def test_complex_app(self): 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ + 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], diff --git a/tests/admin_views/test_nav_sidebar.py b/tests/admin_views/test_nav_sidebar.py index 2225376cd5b3..9d52c541c0d0 100644 --- a/tests/admin_views/test_nav_sidebar.py +++ b/tests/admin_views/test_nav_sidebar.py @@ -51,9 +51,31 @@ def test_sidebar_unauthenticated(self): self.assertNotContains(response, '