mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Merge branch 'django:main' into ticket_34034
This commit is contained in:
@@ -61,7 +61,7 @@ html:
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
htmlview: html
|
||||
$(PYTHON) -c "import webbrowser; webbrowser.open('_build/html/index.html')"
|
||||
$(PYTHON) -m webbrowser "$(BUILDDIR)/html/index.html"
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
|
||||
@@ -13,6 +13,8 @@ import functools
|
||||
import sys
|
||||
from os.path import abspath, dirname, join
|
||||
|
||||
from sphinx import version_info as sphinx_version
|
||||
|
||||
# Workaround for sphinx-build recursion limit overflow:
|
||||
# pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
|
||||
# RuntimeError: maximum recursion depth exceeded while pickling an object
|
||||
@@ -138,13 +140,15 @@ django_next_version = "5.2"
|
||||
extlinks = {
|
||||
"bpo": ("https://bugs.python.org/issue?@action=redirect&bpo=%s", "bpo-%s"),
|
||||
"commit": ("https://github.com/django/django/commit/%s", "%s"),
|
||||
"cve": ("https://nvd.nist.gov/vuln/detail/CVE-%s", "CVE-%s"),
|
||||
"pypi": ("https://pypi.org/project/%s/", "%s"),
|
||||
# A file or directory. GitHub redirects from blob to tree if needed.
|
||||
"source": ("https://github.com/django/django/blob/main/%s", "%s"),
|
||||
"ticket": ("https://code.djangoproject.com/ticket/%s", "#%s"),
|
||||
}
|
||||
|
||||
if sphinx_version < (8, 1):
|
||||
extlinks["cve"] = ("https://www.cve.org/CVERecord?id=CVE-%s", "CVE-%s")
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
# language = None
|
||||
|
||||
@@ -6,12 +6,11 @@ This document describes how to make use of external authentication sources
|
||||
(where the web server sets the ``REMOTE_USER`` environment variable) in your
|
||||
Django applications. This type of authentication solution is typically seen on
|
||||
intranet sites, with single sign-on solutions such as IIS and Integrated
|
||||
Windows Authentication or Apache and `mod_authnz_ldap`_, `CAS`_, `Cosign`_,
|
||||
`WebAuth`_, `mod_auth_sspi`_, etc.
|
||||
Windows Authentication or Apache and `mod_authnz_ldap`_, `CAS`_, `WebAuth`_,
|
||||
`mod_auth_sspi`_, etc.
|
||||
|
||||
.. _mod_authnz_ldap: https://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html
|
||||
.. _mod_authnz_ldap: https://httpd.apache.org/docs/current/mod/mod_authnz_ldap.html
|
||||
.. _CAS: https://www.apereo.org/projects/cas
|
||||
.. _Cosign: http://weblogin.org
|
||||
.. _WebAuth: https://uit.stanford.edu/service/authentication
|
||||
.. _mod_auth_sspi: https://sourceforge.net/projects/mod-auth-sspi
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ You can install Hypercorn with ``pip``:
|
||||
Running Django in Hypercorn
|
||||
===========================
|
||||
|
||||
When Hypercorn is installed, a ``hypercorn`` command is available
|
||||
When :pypi:`Hypercorn` is installed, a ``hypercorn`` command is available
|
||||
which runs ASGI applications. Hypercorn needs to be called with the
|
||||
location of a module containing an ASGI application object, followed
|
||||
by what the application is called (separated by a colon).
|
||||
@@ -35,4 +35,4 @@ this command from the same directory as your ``manage.py`` file.
|
||||
For more advanced usage, please read the `Hypercorn documentation
|
||||
<Hypercorn_>`_.
|
||||
|
||||
.. _Hypercorn: https://pgjones.gitlab.io/hypercorn/
|
||||
.. _Hypercorn: https://hypercorn.readthedocs.io/
|
||||
|
||||
@@ -1,11 +1,57 @@
|
||||
===============
|
||||
"How-to" guides
|
||||
===============
|
||||
=============
|
||||
How-to guides
|
||||
=============
|
||||
|
||||
Here you'll find short answers to "How do I....?" types of questions. These
|
||||
how-to guides don't cover topics in depth -- you'll find that material in the
|
||||
:doc:`/topics/index` and the :doc:`/ref/index`. However, these guides will help
|
||||
you quickly accomplish common tasks.
|
||||
Practical guides covering common tasks and problems.
|
||||
|
||||
Models, data and databases
|
||||
==========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
initial-data
|
||||
legacy-databases
|
||||
custom-model-fields
|
||||
writing-migrations
|
||||
custom-lookups
|
||||
|
||||
Templates and output
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
outputting-csv
|
||||
outputting-pdf
|
||||
overriding-templates
|
||||
custom-template-backend
|
||||
custom-template-tags
|
||||
|
||||
Project configuration and management
|
||||
====================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
static-files/index
|
||||
logging
|
||||
error-reporting
|
||||
delete-app
|
||||
|
||||
Installing, deploying and upgrading
|
||||
===================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
upgrade-version
|
||||
windows
|
||||
deployment/index
|
||||
static-files/deployment
|
||||
|
||||
Other guides
|
||||
============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
@@ -13,25 +59,7 @@ you quickly accomplish common tasks.
|
||||
auth-remote-user
|
||||
csrf
|
||||
custom-management-commands
|
||||
custom-model-fields
|
||||
custom-lookups
|
||||
custom-template-backend
|
||||
custom-template-tags
|
||||
custom-file-storage
|
||||
deployment/index
|
||||
upgrade-version
|
||||
error-reporting
|
||||
initial-data
|
||||
legacy-databases
|
||||
logging
|
||||
outputting-csv
|
||||
outputting-pdf
|
||||
overriding-templates
|
||||
static-files/index
|
||||
static-files/deployment
|
||||
windows
|
||||
writing-migrations
|
||||
delete-app
|
||||
|
||||
.. seealso::
|
||||
|
||||
|
||||
@@ -111,15 +111,15 @@ reimplement the entire template.
|
||||
For example, you can use this technique to add a custom logo to the
|
||||
``admin/base_site.html`` template:
|
||||
|
||||
.. code-block:: html+django
|
||||
:caption: ``templates/admin/base_site.html``
|
||||
.. code-block:: html+django
|
||||
:caption: ``templates/admin/base_site.html``
|
||||
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% extends "admin/base_site.html" %}
|
||||
|
||||
{% block branding %}
|
||||
<img src="link/to/logo.png" alt="logo">
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
{% block branding %}
|
||||
<img src="link/to/logo.png" alt="logo">
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
Key points to note:
|
||||
|
||||
|
||||
@@ -232,47 +232,47 @@
|
||||
</g>
|
||||
<g id="Graphic_89">
|
||||
<rect x="189" y="144" width="243" height="54" fill="white"/>
|
||||
<path d="M 432 198 L 189 198 L 189 144 L 432 144 Z" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<text transform="translate(193 150)" fill="#797979">
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x="19.789062" y="11">The ticket was already reported, was </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x=".8017578" y="25">already rejected, isn't a bug, doesn't contain </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x="1.2792969" y="39">enough information, or can't be reproduced.</tspan>
|
||||
<path d="M 432 198 L 189 198 L 189 144 L 432 144 Z" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<text transform="translate(193 150)" fill="#595959">
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x="19.789062" y="11">The ticket was already reported, was </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x=".8017578" y="25">already rejected, isn't a bug, doesn't contain </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x="1.2792969" y="39">enough information, or can't be reproduced.</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_90">
|
||||
<line x1="252" y1="278.5" x2="252" y2="198" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<line x1="252" y1="278.5" x2="252" y2="198" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_91">
|
||||
<path d="M 258.36395 281.63605 C 261.8787 285.15076 261.8787 290.84924 258.36395 294.36395 C 254.84924 297.8787 249.15076 297.8787 245.63605 294.36395 C 242.1213 290.84924 242.1213 285.15076 245.63605 281.63605 C 249.15076 278.1213 254.84924 278.1213 258.36395 281.63605" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<path d="M 258.36395 281.63605 C 261.8787 285.15076 261.8787 290.84924 258.36395 294.36395 C 254.84924 297.8787 249.15076 297.8787 245.63605 294.36395 C 242.1213 290.84924 242.1213 285.15076 245.63605 281.63605 C 249.15076 278.1213 254.84924 278.1213 258.36395 281.63605" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_96">
|
||||
<rect x="72" y="144" width="99" height="54" fill="white"/>
|
||||
<path d="M 171 198 L 72 198 L 72 144 L 171 144 Z" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<text transform="translate(76 150)" fill="#797979">
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x="8.486328" y="11">The ticket is a </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x="4.463867" y="25">bug and should </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x="22.81836" y="39">be fixed.</tspan>
|
||||
<path d="M 171 198 L 72 198 L 72 144 L 171 144 Z" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<text transform="translate(76 150)" fill="#595959">
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x="8.486328" y="11">The ticket is a </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x="4.463867" y="25">bug and should </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x="22.81836" y="39">be fixed.</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_97">
|
||||
<path d="M 150.36395 317.63605 C 153.87869 321.15076 153.87869 326.84924 150.36395 330.36395 C 146.84924 333.8787 141.15076 333.8787 137.63605 330.36395 C 134.12131 326.84924 134.12131 321.15076 137.63605 317.63605 C 141.15076 314.1213 146.84924 314.1213 150.36395 317.63605" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<path d="M 150.36395 317.63605 C 153.87869 321.15076 153.87869 326.84924 150.36395 330.36395 C 146.84924 333.8787 141.15076 333.8787 137.63605 330.36395 C 134.12131 326.84924 134.12131 321.15076 137.63605 317.63605 C 141.15076 314.1213 146.84924 314.1213 150.36395 317.63605" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_98">
|
||||
<path d="M 134.5 324 L 81 324 L 81 198" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<path d="M 134.5 324 L 81 324 L 81 198" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_102">
|
||||
<rect x="72" y="522" width="342" height="36" fill="white"/>
|
||||
<path d="M 414 558 L 72 558 L 72 522 L 414 522 Z" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<text transform="translate(76 526)" fill="#797979">
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x="7.241211" y="11">The ticket has a patch which applies cleanly and includes all </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#797979" x="26.591797" y="25">needed tests and docs. A merger can commit it as is.</tspan>
|
||||
<path d="M 414 558 L 72 558 L 72 522 L 414 522 Z" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<text transform="translate(76 526)" fill="#595959">
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x="7.241211" y="11">The ticket has a patch which applies cleanly and includes all </tspan>
|
||||
<tspan font-family="Helvetica" font-size="12" fill="#595959" x="26.591797" y="25">needed tests and docs. A merger can commit it as is.</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_103">
|
||||
<path d="M 150.36395 407.63605 C 153.87869 411.15076 153.87869 416.84924 150.36395 420.36395 C 146.84924 423.8787 141.15076 423.8787 137.63605 420.36395 C 134.12131 416.84924 134.12131 411.15076 137.63605 407.63605 C 141.15076 404.1213 146.84924 404.1213 150.36395 407.63605" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<path d="M 150.36395 407.63605 C 153.87869 411.15076 153.87869 416.84924 150.36395 420.36395 C 146.84924 423.8787 141.15076 423.8787 137.63605 420.36395 C 134.12131 416.84924 134.12131 411.15076 137.63605 407.63605 C 141.15076 404.1213 146.84924 404.1213 150.36395 407.63605" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_104">
|
||||
<path d="M 134.5 414 L 81 414 L 81 522" stroke="#aaa" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
<path d="M 134.5 414 L 81 414 L 81 522" stroke="#595959" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_151">
|
||||
<line x1="252" y1="288" x2="303.79966" y2="317.5998" marker-end="url(#FilledArrow_Marker)" stroke="#008f00" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@@ -49,8 +49,8 @@ attribute easily tells us what and who each ticket is waiting on.
|
||||
Since a picture is worth a thousand words, let's start there:
|
||||
|
||||
.. image:: /internals/_images/triage_process.*
|
||||
:height: 501
|
||||
:width: 400
|
||||
:height: 750
|
||||
:width: 600
|
||||
:alt: Django's ticket triage workflow
|
||||
|
||||
We've got two roles in this diagram:
|
||||
|
||||
@@ -417,7 +417,7 @@ Model style
|
||||
* All database fields
|
||||
* Custom manager attributes
|
||||
* ``class Meta``
|
||||
* ``def __str__()``
|
||||
* ``def __str__()`` and other Python magic methods
|
||||
* ``def save()``
|
||||
* ``def get_absolute_url()``
|
||||
* Any custom methods
|
||||
|
||||
@@ -114,7 +114,7 @@ requirements:
|
||||
feature, the change should also contain documentation.
|
||||
|
||||
When you think your work is ready to be reviewed, send :doc:`a GitHub pull
|
||||
request <working-with-git>`.
|
||||
request <working-with-git>`.
|
||||
If you can't send a pull request for some reason, you can also use patches in
|
||||
Trac. When using this style, follow these guidelines.
|
||||
|
||||
@@ -140,20 +140,63 @@ Regardless of the way you submit your work, follow these steps.
|
||||
.. _ticket tracker: https://code.djangoproject.com/
|
||||
.. _Development dashboard: https://dashboard.djangoproject.com/
|
||||
|
||||
Non-trivial contributions
|
||||
=========================
|
||||
Contributions which require community feedback
|
||||
==============================================
|
||||
|
||||
A "non-trivial" contribution is one that is more than a small bug fix. It's a
|
||||
change that introduces new Django functionality and makes some sort of design
|
||||
decision.
|
||||
A wider community discussion is required when a patch introduces new Django
|
||||
functionality and makes some sort of design decision. This is especially
|
||||
important if the approach involves a :ref:`deprecation <deprecating-a-feature>`
|
||||
or introduces breaking changes.
|
||||
|
||||
If you provide a non-trivial change, include evidence that alternatives have
|
||||
been discussed on the `Django Forum`_ or |django-developers| list.
|
||||
The following are different approaches for gaining feedback from the community.
|
||||
|
||||
If you're not sure whether your contribution should be considered non-trivial,
|
||||
ask on the ticket for opinions.
|
||||
The Django Forum or django-developers mailing list
|
||||
--------------------------------------------------
|
||||
|
||||
You can propose a change on the `Django Forum`_ or |django-developers| mailing
|
||||
list. You should explain the need for the change, go into details of the
|
||||
approach and discuss alternatives.
|
||||
|
||||
Please include a link to such discussions in your contributions.
|
||||
|
||||
Third party package
|
||||
-------------------
|
||||
|
||||
Django does not accept experimental features. All features must follow our
|
||||
:ref:`deprecation policy <internal-release-deprecation-policy>`. Hence, it can
|
||||
take months or years for Django to iterate on an API design.
|
||||
|
||||
If you need user feedback on a public interface, it is better to create a
|
||||
third-party package first. You can iterate on the public API much faster, while
|
||||
also validating the need for the feature.
|
||||
|
||||
Once this package becomes stable and there are clear benefits of incorporating
|
||||
aspects into Django core, starting a discussion on the `Django Forum`_ or
|
||||
|django-developers| mailing list would be the next step.
|
||||
|
||||
Django Enhancement Proposal (DEP)
|
||||
---------------------------------
|
||||
|
||||
Similar to Python’s PEPs, Django has `Django Enhancement Proposals`_ or DEPs. A
|
||||
DEP is a design document which provides information to the Django community, or
|
||||
describes a new feature or process for Django. They provide concise technical
|
||||
specifications of features, along with rationales. DEPs are also the primary
|
||||
mechanism for proposing and collecting community input on major new features.
|
||||
|
||||
Before considering writing a DEP, it is recommended to first open a discussion
|
||||
on the `Django Forum`_ or |django-developers| mailing list. This allows the
|
||||
community to provide feedback and helps refine the proposal. Once the DEP is
|
||||
ready the :ref:`Steering Council <steering-council>` votes on whether to accept
|
||||
it.
|
||||
|
||||
Some examples of DEPs that have been approved and fully implemented:
|
||||
|
||||
* `DEP 181: ORM Expressions <https://github.com/django/deps/blob/main/final/0181-orm-expressions.rst>`_
|
||||
* `DEP 182: Multiple Template Engines <https://github.com/django/deps/blob/main/final/0182-multiple-template-engines.rst>`_
|
||||
* `DEP 201: Simplified routing syntax <https://github.com/django/deps/blob/main/final/0201-simplified-routing-syntax.rst>`_
|
||||
|
||||
.. _Django Forum: https://forum.djangoproject.com/
|
||||
.. _Django Enhancement Proposals: https://github.com/django/deps
|
||||
|
||||
.. _deprecating-a-feature:
|
||||
|
||||
|
||||
@@ -159,9 +159,14 @@ Spelling check
|
||||
|
||||
Before you commit your docs, it's a good idea to run the spelling checker.
|
||||
You'll need to install :pypi:`sphinxcontrib-spelling` first. Then from the
|
||||
``docs`` directory, run ``make spelling``. Wrong words (if any) along with the
|
||||
file and line number where they occur will be saved to
|
||||
``_build/spelling/output.txt``.
|
||||
``docs`` directory, run:
|
||||
|
||||
.. console::
|
||||
|
||||
$ make spelling
|
||||
|
||||
Wrong words (if any) along with the file and line number where they occur will
|
||||
be saved to ``_build/spelling/output.txt``.
|
||||
|
||||
If you encounter false-positives (error output that actually is correct), do
|
||||
one of the following:
|
||||
@@ -179,10 +184,21 @@ Link check
|
||||
|
||||
Links in documentation can become broken or changed such that they are no
|
||||
longer the canonical link. Sphinx provides a builder that can check whether the
|
||||
links in the documentation are working. From the ``docs`` directory, run ``make
|
||||
linkcheck``. Output is printed to the terminal, but can also be found in
|
||||
links in the documentation are working. From the ``docs`` directory, run:
|
||||
|
||||
.. console::
|
||||
|
||||
$ make linkcheck
|
||||
|
||||
Output is printed to the terminal, but can also be found in
|
||||
``_build/linkcheck/output.txt`` and ``_build/linkcheck/output.json``.
|
||||
|
||||
.. warning::
|
||||
|
||||
The execution of the command requires an internet connection and takes
|
||||
several minutes to complete, because the command tests all the links
|
||||
that are found in the documentation.
|
||||
|
||||
Entries that have a status of "working" are fine, those that are "unchecked" or
|
||||
"ignored" have been skipped because they either cannot be checked or have
|
||||
matched ignore rules in the configuration.
|
||||
@@ -290,7 +306,8 @@ documentation:
|
||||
display a link with the title "auth".
|
||||
|
||||
* All Python code blocks should be formatted using the :pypi:`blacken-docs`
|
||||
auto-formatter. This will be run by ``pre-commit`` if that is configured.
|
||||
auto-formatter. This will be run by :ref:`pre-commit
|
||||
<coding-style-pre-commit>` if that is configured.
|
||||
|
||||
* Use :mod:`~sphinx.ext.intersphinx` to reference Python's and Sphinx'
|
||||
documentation.
|
||||
@@ -324,8 +341,9 @@ documentation:
|
||||
Five
|
||||
^^^^
|
||||
|
||||
* Use :rst:role:`:rfc:<rfc>` to reference RFC and try to link to the relevant
|
||||
section if possible. For example, use ``:rfc:`2324#section-2.3.2``` or
|
||||
* Use :rst:role:`:rfc:<rfc>` to reference a Request for Comments (RFC) and
|
||||
try to link to the relevant 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:<pep>` to reference a Python Enhancement Proposal (PEP)
|
||||
@@ -339,6 +357,9 @@ documentation:
|
||||
also need to define a reference to the documentation for that environment
|
||||
variable using :rst:dir:`.. envvar:: <envvar>`.
|
||||
|
||||
* Use :rst:role:`:cve:<cve>` to reference a Common Vulnerabilities and
|
||||
Exposures (CVE) identifier. For example, use ``:cve:`2019-14232```.
|
||||
|
||||
Django-specific markup
|
||||
======================
|
||||
|
||||
@@ -518,7 +539,7 @@ Minimizing images
|
||||
Optimize image compression where possible. For PNG files, use OptiPNG and
|
||||
AdvanceCOMP's ``advpng``:
|
||||
|
||||
.. code-block:: console
|
||||
.. console::
|
||||
|
||||
$ cd docs
|
||||
$ optipng -o7 -zm1-9 -i0 -strip all `find . -type f -not -path "./_build/*" -name "*.png"`
|
||||
@@ -619,6 +640,10 @@ included in the Django repository and the releases as
|
||||
``docs/man/django-admin.1``. There isn't a need to update this file when
|
||||
updating the documentation, as it's updated once as part of the release process.
|
||||
|
||||
To generate an updated version of the man page, run ``make man`` in the
|
||||
``docs`` directory. The new man page will be written in
|
||||
``docs/_build/man/django-admin.1``.
|
||||
To generate an updated version of the man page, in the ``docs`` directory, run:
|
||||
|
||||
.. console::
|
||||
|
||||
$ make man
|
||||
|
||||
The new man page will be written in ``docs/_build/man/django-admin.1``.
|
||||
|
||||
@@ -38,6 +38,41 @@ action to be taken, you may receive further followup emails.
|
||||
|
||||
.. _our public Trac instance: https://code.djangoproject.com/query
|
||||
|
||||
.. _security-report-evaluation:
|
||||
|
||||
How does Django evaluate a report
|
||||
=================================
|
||||
|
||||
These are criteria used by the security team when evaluating whether a report
|
||||
requires a security release:
|
||||
|
||||
* The vulnerability is within a :ref:`supported version <security-support>` of
|
||||
Django.
|
||||
|
||||
* The vulnerability applies to a production-grade Django application. This means
|
||||
the following do not require a security release:
|
||||
|
||||
* Exploits that only affect local development, for example when using
|
||||
:djadmin:`runserver`.
|
||||
* Exploits which fail to follow security best practices, such as failure to
|
||||
sanitize user input. For other examples, see our :ref:`security
|
||||
documentation <cross-site-scripting>`.
|
||||
* Exploits in AI generated code that do not adhere to security best practices.
|
||||
|
||||
The security team may conclude that the source of the vulnerability is within
|
||||
the Python standard library, in which case the reporter will be asked to report
|
||||
the vulnerability to the Python core team. For further details see the `Python
|
||||
security guidelines <https://www.python.org/dev/security/>`_.
|
||||
|
||||
On occasion, a security release may be issued to help resolve a security
|
||||
vulnerability within a popular third-party package. These reports should come
|
||||
from the package maintainers.
|
||||
|
||||
If you are unsure whether your finding meets these criteria, please still report
|
||||
it :ref:`privately by emailing security@djangoproject.com
|
||||
<reporting-security-issues>`. The security team will review your report and
|
||||
recommend the correct course of action.
|
||||
|
||||
.. _security-support:
|
||||
|
||||
Supported versions
|
||||
|
||||
@@ -217,8 +217,7 @@ a dependency for one or more of the Python packages. Consult the failing
|
||||
package's documentation or search the web with the error message that you
|
||||
encounter.
|
||||
|
||||
Now we are ready to run the test suite. If you're using GNU/Linux, macOS, or
|
||||
some other flavor of Unix, run:
|
||||
Now we are ready to run the test suite:
|
||||
|
||||
.. console::
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ Here's what the "base.html" template, including the use of :doc:`static files
|
||||
:caption: ``templates/base.html``
|
||||
|
||||
{% load static %}
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
</head>
|
||||
|
||||
@@ -6,7 +6,7 @@ This advanced tutorial begins where :doc:`Tutorial 8 </intro/tutorial08>`
|
||||
left off. We'll be turning our web-poll into a standalone Python package
|
||||
you can reuse in new projects and share with other people.
|
||||
|
||||
If you haven't recently completed Tutorials 1–7, we encourage you to review
|
||||
If you haven't recently completed Tutorials 1–8, we encourage you to review
|
||||
these so that your example project matches the one described below.
|
||||
|
||||
Reusability matters
|
||||
|
||||
@@ -293,7 +293,8 @@ app will still work.
|
||||
.. admonition:: When to use :func:`~django.urls.include()`
|
||||
|
||||
You should always use ``include()`` when you include other URL patterns.
|
||||
``admin.site.urls`` is the only exception to this.
|
||||
The only exception is ``admin.site.urls``, which is a pre-built URLconf
|
||||
provided by Django for the default admin site.
|
||||
|
||||
You have now wired an ``index`` view into the URLconf. Verify it's working with
|
||||
the following command:
|
||||
|
||||
@@ -77,6 +77,7 @@ Django's system checks are organized using the following tags:
|
||||
* ``async_support``: Checks asynchronous-related configuration.
|
||||
* ``caches``: Checks cache related configuration.
|
||||
* ``compatibility``: Flags potential problems with version upgrades.
|
||||
* ``commands``: Checks custom management commands related configuration.
|
||||
* ``database``: Checks database-related configuration issues. Database checks
|
||||
are not run by default because they do more than static code analysis as
|
||||
regular checks do. They are only run by the :djadmin:`migrate` command or if
|
||||
@@ -428,6 +429,14 @@ Models
|
||||
* **models.W047**: ``<database>`` does not support unique constraints with
|
||||
nulls distinct.
|
||||
|
||||
Management Commands
|
||||
-------------------
|
||||
|
||||
The following checks verify custom management commands are correctly configured:
|
||||
|
||||
* **commands.E001**: The ``migrate`` and ``makemigrations`` commands must have
|
||||
the same ``autodetector``.
|
||||
|
||||
Security
|
||||
--------
|
||||
|
||||
|
||||
@@ -337,7 +337,8 @@ subclass::
|
||||
If neither ``fields`` nor :attr:`~ModelAdmin.fieldsets` options are present,
|
||||
Django will default to displaying each field that isn't an ``AutoField`` and
|
||||
has ``editable=True``, in a single fieldset, in the same order as the fields
|
||||
are defined in the model.
|
||||
are defined in the model, followed by any fields defined in
|
||||
:attr:`~ModelAdmin.readonly_fields`.
|
||||
|
||||
.. attribute:: ModelAdmin.fieldsets
|
||||
|
||||
@@ -1465,6 +1466,27 @@ templates used by the :class:`ModelAdmin` views:
|
||||
|
||||
See also :ref:`saving-objects-in-the-formset`.
|
||||
|
||||
.. warning::
|
||||
|
||||
All hooks that return a ``ModelAdmin`` property return the property itself
|
||||
rather than a copy of its value. Dynamically modifying the value can lead
|
||||
to surprising results.
|
||||
|
||||
Let's take :meth:`ModelAdmin.get_readonly_fields` as an example::
|
||||
|
||||
class PersonAdmin(admin.ModelAdmin):
|
||||
readonly_fields = ["name"]
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
readonly = super().get_readonly_fields(request, obj)
|
||||
if not request.user.is_superuser:
|
||||
readonly.append("age") # Edits the class attribute.
|
||||
return readonly
|
||||
|
||||
This results in ``readonly_fields`` becoming
|
||||
``["name", "age", "age", ...]``, even for a superuser, as ``"age"`` is added
|
||||
each time non-superuser visits the page.
|
||||
|
||||
.. method:: ModelAdmin.get_ordering(request)
|
||||
|
||||
The ``get_ordering`` method takes a ``request`` as parameter and
|
||||
|
||||
@@ -54,7 +54,8 @@ Fields
|
||||
|
||||
Required. A hash of, and metadata about, the password. (Django doesn't
|
||||
store the raw password.) Raw passwords can be arbitrarily long and can
|
||||
contain any character. See the :doc:`password documentation
|
||||
contain any character. The metadata in this field may mark the password
|
||||
as unusable. See the :doc:`password documentation
|
||||
</topics/auth/passwords>`.
|
||||
|
||||
.. attribute:: groups
|
||||
@@ -175,8 +176,9 @@ Methods
|
||||
|
||||
.. method:: set_unusable_password()
|
||||
|
||||
Marks the user as having no password set. This isn't the same as
|
||||
having a blank string for a password.
|
||||
Marks the user as having no password set by updating the metadata in
|
||||
the :attr:`~django.contrib.auth.models.User.password` field. This isn't
|
||||
the same as having a blank string for a password.
|
||||
:meth:`~django.contrib.auth.models.User.check_password()` for this user
|
||||
will never return ``True``. Doesn't save the
|
||||
:class:`~django.contrib.auth.models.User` object.
|
||||
|
||||
@@ -256,7 +256,7 @@ Here's a sample :file:`flatpages/default.html` template:
|
||||
.. code-block:: html+django
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ flatpage.title }}</title>
|
||||
</head>
|
||||
|
||||
@@ -339,42 +339,42 @@ divided into the three categories described in the :ref:`raster lookup details
|
||||
<spatial-lookup-raster>`: native support ``N``, bilateral native support ``B``,
|
||||
and geometry conversion support ``C``.
|
||||
|
||||
================================= ========= ======== ========= ============ ========== ========
|
||||
Lookup Type PostGIS Oracle MariaDB MySQL [#]_ SpatiaLite PGRaster
|
||||
================================= ========= ======== ========= ============ ========== ========
|
||||
:lookup:`bbcontains` X X X X N
|
||||
:lookup:`bboverlaps` X X X X N
|
||||
:lookup:`contained` X X X X N
|
||||
:lookup:`contains <gis-contains>` X X X X X B
|
||||
:lookup:`contains_properly` X B
|
||||
:lookup:`coveredby` X X X B
|
||||
:lookup:`covers` X X X B
|
||||
:lookup:`crosses` X X X X C
|
||||
:lookup:`disjoint` X X X X X B
|
||||
:lookup:`distance_gt` X X X X X N
|
||||
:lookup:`distance_gte` X X X X X N
|
||||
:lookup:`distance_lt` X X X X X N
|
||||
:lookup:`distance_lte` X X X X X N
|
||||
:lookup:`dwithin` X X X B
|
||||
:lookup:`equals` X X X X X C
|
||||
:lookup:`exact <same_as>` X X X X X B
|
||||
:lookup:`intersects` X X X X X B
|
||||
================================= ========= ======== ========== ============ ========== ========
|
||||
Lookup Type PostGIS Oracle MariaDB MySQL [#]_ SpatiaLite PGRaster
|
||||
================================= ========= ======== ========== ============ ========== ========
|
||||
:lookup:`bbcontains` X X X X N
|
||||
:lookup:`bboverlaps` X X X X N
|
||||
:lookup:`contained` X X X X N
|
||||
:lookup:`contains <gis-contains>` X X X X X B
|
||||
:lookup:`contains_properly` X B
|
||||
:lookup:`coveredby` X X X (≥ 11.7) X X B
|
||||
:lookup:`covers` X X X X B
|
||||
:lookup:`crosses` X X X X C
|
||||
:lookup:`disjoint` X X X X X B
|
||||
:lookup:`distance_gt` X X X X X N
|
||||
:lookup:`distance_gte` X X X X X N
|
||||
:lookup:`distance_lt` X X X X X N
|
||||
:lookup:`distance_lte` X X X X X N
|
||||
:lookup:`dwithin` X X X B
|
||||
:lookup:`equals` X X X X X C
|
||||
:lookup:`exact <same_as>` X X X X X B
|
||||
:lookup:`intersects` X X X X X B
|
||||
:lookup:`isempty` X
|
||||
:lookup:`isvalid` X X X X
|
||||
:lookup:`overlaps` X X X X X B
|
||||
:lookup:`relate` X X X X C
|
||||
:lookup:`same_as` X X X X X B
|
||||
:lookup:`touches` X X X X X B
|
||||
:lookup:`within` X X X X X B
|
||||
:lookup:`left` X C
|
||||
:lookup:`right` X C
|
||||
:lookup:`overlaps_left` X B
|
||||
:lookup:`overlaps_right` X B
|
||||
:lookup:`overlaps_above` X C
|
||||
:lookup:`overlaps_below` X C
|
||||
:lookup:`strictly_above` X C
|
||||
:lookup:`strictly_below` X C
|
||||
================================= ========= ======== ========= ============ ========== ========
|
||||
:lookup:`isvalid` X X X (≥ 11.7) X X
|
||||
:lookup:`overlaps` X X X X X B
|
||||
:lookup:`relate` X X X X C
|
||||
:lookup:`same_as` X X X X X B
|
||||
:lookup:`touches` X X X X X B
|
||||
:lookup:`within` X X X X X B
|
||||
:lookup:`left` X C
|
||||
:lookup:`right` X C
|
||||
:lookup:`overlaps_left` X B
|
||||
:lookup:`overlaps_right` X B
|
||||
:lookup:`overlaps_above` X C
|
||||
:lookup:`overlaps_below` X C
|
||||
:lookup:`strictly_above` X C
|
||||
:lookup:`strictly_below` X C
|
||||
================================= ========= ======== ========== ============ ========== ========
|
||||
|
||||
.. _database-functions-compatibility:
|
||||
|
||||
@@ -406,10 +406,10 @@ Function PostGIS Oracle MariaDB MySQL
|
||||
:class:`ForcePolygonCW` X X
|
||||
:class:`FromWKB` X X X X X
|
||||
:class:`FromWKT` X X X X X
|
||||
:class:`GeoHash` X X X (LWGEOM/RTTOPO)
|
||||
:class:`GeoHash` X X (≥ 11.7) X X (LWGEOM/RTTOPO)
|
||||
:class:`Intersection` X X X X X
|
||||
:class:`IsEmpty` X
|
||||
:class:`IsValid` X X X X
|
||||
:class:`IsValid` X X X (≥ 11.7) X X
|
||||
:class:`Length` X X X X X
|
||||
:class:`LineLocatePoint` X X
|
||||
:class:`MakeValid` X X (LWGEOM/RTTOPO)
|
||||
@@ -431,20 +431,19 @@ Aggregate Functions
|
||||
-------------------
|
||||
|
||||
The following table provides a summary of what GIS-specific aggregate functions
|
||||
are available on each spatial backend. Please note that MariaDB does not
|
||||
support any of these aggregates, and is thus excluded from the table.
|
||||
are available on each spatial backend.
|
||||
|
||||
.. currentmodule:: django.contrib.gis.db.models
|
||||
|
||||
======================= ======= ====== ============ ==========
|
||||
Aggregate PostGIS Oracle MySQL SpatiaLite
|
||||
======================= ======= ====== ============ ==========
|
||||
:class:`Collect` X X (≥ 8.0.24) X
|
||||
:class:`Extent` X X X
|
||||
======================= ======= ====== ========== ============ ==========
|
||||
Aggregate PostGIS Oracle MariaDB MySQL SpatiaLite
|
||||
======================= ======= ====== ========== ============ ==========
|
||||
:class:`Collect` X X (≥ 11.7) X (≥ 8.0.24) X
|
||||
:class:`Extent` X X X
|
||||
:class:`Extent3D` X
|
||||
:class:`MakeLine` X X
|
||||
:class:`Union` X X X
|
||||
======================= ======= ====== ============ ==========
|
||||
:class:`MakeLine` X X
|
||||
:class:`Union` X X X
|
||||
======================= ======= ====== ========== ============ ==========
|
||||
|
||||
.. rubric:: Footnotes
|
||||
.. [#fnwkt] *See* Open Geospatial Consortium, Inc., `OpenGIS Simple Feature Specification For SQL <https://portal.ogc.org/files/?artifact_id=829>`_, Document 99-049 (May 5, 1999), at Ch. 3.2.5, p. 3-11 (SQL Textual Representation of Geometry).
|
||||
|
||||
@@ -393,7 +393,7 @@ Creates geometry from `Well-known text (WKT)`_ representation. The optional
|
||||
|
||||
.. class:: GeoHash(expression, precision=None, **extra)
|
||||
|
||||
*Availability*: `MySQL
|
||||
*Availability*: MariaDB, `MySQL
|
||||
<https://dev.mysql.com/doc/refman/en/spatial-geohash-functions.html#function_st-geohash>`__,
|
||||
`PostGIS <https://postgis.net/docs/ST_GeoHash.html>`__, SpatiaLite
|
||||
(LWGEOM/RTTOPO)
|
||||
@@ -406,6 +406,10 @@ result.
|
||||
|
||||
__ https://en.wikipedia.org/wiki/Geohash
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
MariaDB 11.7+ support was added.
|
||||
|
||||
``GeometryDistance``
|
||||
====================
|
||||
|
||||
@@ -444,13 +448,17 @@ geometry. Returns ``True`` if its value is empty and ``False`` otherwise.
|
||||
|
||||
.. class:: IsValid(expr)
|
||||
|
||||
*Availability*: `MySQL
|
||||
*Availability*: MariaDB, `MySQL
|
||||
<https://dev.mysql.com/doc/refman/en/spatial-convenience-functions.html#function_st-isvalid>`__,
|
||||
`PostGIS <https://postgis.net/docs/ST_IsValid.html>`__, Oracle, SpatiaLite
|
||||
|
||||
Accepts a geographic field or expression and tests if the value is well formed.
|
||||
Returns ``True`` if its value is a valid geometry and ``False`` otherwise.
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
MariaDB 11.7+ support was added.
|
||||
|
||||
``Length``
|
||||
==========
|
||||
|
||||
|
||||
@@ -611,6 +611,26 @@ coordinate transformation:
|
||||
>>> polygon.geom_count
|
||||
1
|
||||
|
||||
.. attribute:: has_curve
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
A boolean indicating if this geometry is or contains a curve geometry.
|
||||
|
||||
.. method:: get_linear_geometry
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
Returns a linear version of the geometry. If no conversion can be made, the
|
||||
original geometry is returned.
|
||||
|
||||
.. method:: get_curve_geometry
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
Returns a curved version of the geometry. If no conversion can be made, the
|
||||
original geometry is returned.
|
||||
|
||||
.. attribute:: point_count
|
||||
|
||||
Returns the number of points used to describe this geometry:
|
||||
|
||||
@@ -183,7 +183,7 @@ PostGIS ``ST_ContainsProperly(poly, geom)``
|
||||
-------------
|
||||
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_CoveredBy.html>`__,
|
||||
Oracle, PGRaster (Bilateral), SpatiaLite
|
||||
Oracle, MariaDB 11.7+, MySQL, PGRaster (Bilateral), SpatiaLite
|
||||
|
||||
Tests if no point in the geometry field is outside the lookup geometry.
|
||||
[#fncovers]_
|
||||
@@ -197,16 +197,22 @@ Backend SQL Equivalent
|
||||
========== =============================
|
||||
PostGIS ``ST_CoveredBy(poly, geom)``
|
||||
Oracle ``SDO_COVEREDBY(poly, geom)``
|
||||
MariaDB ``MBRCoveredBy(poly, geom)``
|
||||
MySQL ``MBRCoveredBy(poly, geom)``
|
||||
SpatiaLite ``CoveredBy(poly, geom)``
|
||||
========== =============================
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
MySQL and MariaDB 11.7+ support was added.
|
||||
|
||||
.. fieldlookup:: covers
|
||||
|
||||
``covers``
|
||||
----------
|
||||
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_Covers.html>`__,
|
||||
Oracle, PGRaster (Bilateral), SpatiaLite
|
||||
Oracle, MySQL, PGRaster (Bilateral), SpatiaLite
|
||||
|
||||
Tests if no point in the lookup geometry is outside the geometry field.
|
||||
[#fncovers]_
|
||||
@@ -220,9 +226,14 @@ Backend SQL Equivalent
|
||||
========== ==========================
|
||||
PostGIS ``ST_Covers(poly, geom)``
|
||||
Oracle ``SDO_COVERS(poly, geom)``
|
||||
MySQL ``MBRCovers(poly, geom)``
|
||||
SpatiaLite ``Covers(poly, geom)``
|
||||
========== ==========================
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
MySQL support was added.
|
||||
|
||||
.. fieldlookup:: crosses
|
||||
|
||||
``crosses``
|
||||
@@ -364,8 +375,8 @@ Example::
|
||||
``isvalid``
|
||||
-----------
|
||||
|
||||
*Availability*: MySQL, `PostGIS <https://postgis.net/docs/ST_IsValid.html>`__,
|
||||
Oracle, SpatiaLite
|
||||
*Availability*: MariaDB, MySQL,
|
||||
`PostGIS <https://postgis.net/docs/ST_IsValid.html>`__, Oracle, SpatiaLite
|
||||
|
||||
Tests if the geometry is valid.
|
||||
|
||||
@@ -373,12 +384,16 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__isvalid=True)
|
||||
|
||||
========================== ================================================================
|
||||
Backend SQL Equivalent
|
||||
========================== ================================================================
|
||||
MySQL, PostGIS, SpatiaLite ``ST_IsValid(poly)``
|
||||
Oracle ``SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(poly, 0.05) = 'TRUE'``
|
||||
========================== ================================================================
|
||||
=================================== ================================================================
|
||||
Backend SQL Equivalent
|
||||
=================================== ================================================================
|
||||
MariaDB, MySQL, PostGIS, SpatiaLite ``ST_IsValid(poly)``
|
||||
Oracle ``SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(poly, 0.05) = 'TRUE'``
|
||||
=================================== ================================================================
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
MariaDB 11.7+ support was added.
|
||||
|
||||
.. fieldlookup:: overlaps
|
||||
|
||||
@@ -870,8 +885,8 @@ Example:
|
||||
|
||||
.. class:: Collect(geo_field, filter=None)
|
||||
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_Collect.html>`__, MySQL,
|
||||
SpatiaLite
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_Collect.html>`__,
|
||||
MariaDB, MySQL, SpatiaLite
|
||||
|
||||
Returns a ``GEOMETRYCOLLECTION`` or a ``MULTI`` geometry object from the geometry
|
||||
column. This is analogous to a simplified version of the :class:`Union`
|
||||
@@ -883,6 +898,10 @@ caring about dissolving boundaries.
|
||||
|
||||
MySQL 8.0.24+ support was added.
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
MariaDB 11.7+ support was added.
|
||||
|
||||
``Extent``
|
||||
~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -11,7 +11,25 @@ Django provides convenient ways to access the default storage class:
|
||||
|
||||
.. data:: storages
|
||||
|
||||
Storage instances as defined by :setting:`STORAGES`.
|
||||
A dictionary-like object that allows retrieving a storage instance using
|
||||
its alias as defined by :setting:`STORAGES`.
|
||||
|
||||
``storages`` has an attribute ``backends``, which defaults to the raw value
|
||||
provided in :setting:`STORAGES`.
|
||||
|
||||
Additionally, ``storages`` provides a ``create_storage()`` method that
|
||||
accepts the dictionary used in :setting:`STORAGES` for a backend, and
|
||||
returns a storage instance based on that backend definition. This may be
|
||||
useful for third-party packages needing to instantiate storages in tests:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from django.core.files.storage import storages
|
||||
>>> storages.backends
|
||||
{'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'},
|
||||
'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'},
|
||||
'custom': {'BACKEND': 'package.storage.CustomStorage'}}
|
||||
>>> storage_instance = storages.create_storage({"BACKEND": "package.storage.CustomStorage"})
|
||||
|
||||
.. class:: DefaultStorage
|
||||
|
||||
|
||||
@@ -406,8 +406,8 @@ process:
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> f.base_fields["subject"].label_suffix = "?"
|
||||
>>> another_f = CommentForm(auto_id=False)
|
||||
>>> f.as_div().split("</div>")[0]
|
||||
>>> another_f = ContactForm(auto_id=False)
|
||||
>>> another_f.as_div().split("</div>")[0]
|
||||
'<div><label for="id_subject">Subject?</label><input type="text" name="subject" maxlength="100" required id="id_subject">'
|
||||
|
||||
Accessing "clean" data
|
||||
@@ -511,7 +511,7 @@ empty string, because ``nick_name`` is ``CharField``, and ``CharField``\s treat
|
||||
empty values as an empty string. Each field type knows what its "blank" value
|
||||
is -- e.g., for ``DateField``, it's ``None`` instead of the empty string. For
|
||||
full details on each field's behavior in this case, see the "Empty value" note
|
||||
for each field in the "Built-in ``Field`` classes" section below.
|
||||
for each field in the :ref:`built-in-fields` section below.
|
||||
|
||||
You can write code to perform validation for particular form fields (based on
|
||||
their name) or for the form as a whole (considering combinations of various
|
||||
@@ -770,7 +770,7 @@ The template used by ``as_table()``. Default: ``'django/forms/table.html'``.
|
||||
>>> f = ContactForm()
|
||||
>>> f.as_table()
|
||||
'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" required></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" required></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" required></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself"></td></tr>'
|
||||
>>> print(f)
|
||||
>>> print(f.as_table())
|
||||
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" required></td></tr>
|
||||
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" required></td></tr>
|
||||
<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" required></td></tr>
|
||||
|
||||
@@ -282,27 +282,47 @@ PostgreSQL 15+.
|
||||
|
||||
.. attribute:: UniqueConstraint.violation_error_code
|
||||
|
||||
The error code used when ``ValidationError`` is raised during
|
||||
:ref:`model validation <validating-objects>`. Defaults to ``None``.
|
||||
The error code used when a ``ValidationError`` is raised during
|
||||
:ref:`model validation <validating-objects>`.
|
||||
|
||||
This code is *not used* for :class:`UniqueConstraint`\s with
|
||||
:attr:`~UniqueConstraint.fields` and without a
|
||||
:attr:`~UniqueConstraint.condition`. Such :class:`~UniqueConstraint`\s have the
|
||||
same error code as constraints defined with :attr:`.Field.unique` or in
|
||||
:attr:`Meta.unique_together <django.db.models.Options.constraints>`.
|
||||
Defaults to :attr:`.BaseConstraint.violation_error_code`, when either
|
||||
:attr:`.UniqueConstraint.condition` is set or :attr:`.UniqueConstraint.fields`
|
||||
is not set.
|
||||
|
||||
If :attr:`.UniqueConstraint.fields` is set without a
|
||||
:attr:`.UniqueConstraint.condition`, defaults to the :attr:`Meta.unique_together
|
||||
<django.db.models.Options.unique_together>` error code when there are multiple
|
||||
fields, and to the :attr:`.Field.unique` error code when there is a single
|
||||
field.
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
In older versions, the provided
|
||||
:attr:`.UniqueConstraint.violation_error_code` was not used when
|
||||
:attr:`.UniqueConstraint.fields` was set without a
|
||||
:attr:`.UniqueConstraint.condition`.
|
||||
|
||||
``violation_error_message``
|
||||
---------------------------
|
||||
|
||||
.. attribute:: UniqueConstraint.violation_error_message
|
||||
|
||||
The error message used when ``ValidationError`` is raised during
|
||||
:ref:`model validation <validating-objects>`. Defaults to
|
||||
:attr:`.BaseConstraint.violation_error_message`.
|
||||
The error message used when a ``ValidationError`` is raised during
|
||||
:ref:`model validation <validating-objects>`.
|
||||
|
||||
This message is *not used* for :class:`UniqueConstraint`\s with
|
||||
:attr:`~UniqueConstraint.fields` and without a
|
||||
:attr:`~UniqueConstraint.condition`. Such :class:`~UniqueConstraint`\s show the
|
||||
same message as constraints defined with
|
||||
:attr:`.Field.unique` or in
|
||||
:attr:`Meta.unique_together <django.db.models.Options.constraints>`.
|
||||
Defaults to :attr:`.BaseConstraint.violation_error_message`, when either
|
||||
:attr:`.UniqueConstraint.condition` is set or :attr:`.UniqueConstraint.fields`
|
||||
is not set.
|
||||
|
||||
If :attr:`.UniqueConstraint.fields` is set without a
|
||||
:attr:`.UniqueConstraint.condition`, defaults to the :attr:`Meta.unique_together
|
||||
<django.db.models.Options.unique_together>` error message when there are
|
||||
multiple fields, and to the :attr:`.Field.unique` error message when there is a
|
||||
single field.
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
In older versions, the provided
|
||||
:attr:`.UniqueConstraint.violation_error_message` was not used when
|
||||
:attr:`.UniqueConstraint.fields` was set without a
|
||||
:attr:`.UniqueConstraint.condition`.
|
||||
|
||||
@@ -22,9 +22,9 @@ This document contains all the API references of :class:`Field` including the
|
||||
|
||||
.. note::
|
||||
|
||||
Technically, these models are defined in :mod:`django.db.models.fields`, but
|
||||
for convenience they're imported into :mod:`django.db.models`; the standard
|
||||
convention is to use ``from django.db import models`` and refer to fields as
|
||||
Fields are defined in :mod:`django.db.models.fields`, but for convenience
|
||||
they're imported into :mod:`django.db.models`. The standard convention is
|
||||
to use ``from django.db import models`` and refer to fields as
|
||||
``models.<Foo>Field``.
|
||||
|
||||
.. _common-model-field-options:
|
||||
@@ -426,6 +426,11 @@ precedence when creating instances in Python code. ``db_default`` will still be
|
||||
set at the database level and will be used when inserting rows outside of the
|
||||
ORM or when adding a new field in a migration.
|
||||
|
||||
If a field has a ``db_default`` without a ``default`` set and no value is
|
||||
assigned to the field, a ``DatabaseDefault`` object is returned as the field
|
||||
value on unsaved model instances. The actual value for the field is determined
|
||||
by the database when the model instance is saved.
|
||||
|
||||
``db_index``
|
||||
------------
|
||||
|
||||
@@ -1628,80 +1633,25 @@ Django also defines a set of fields that represent relations.
|
||||
.. class:: ForeignKey(to, on_delete, **options)
|
||||
|
||||
A many-to-one relationship. Requires two positional arguments: the class to
|
||||
which the model is related and the :attr:`~ForeignKey.on_delete` option.
|
||||
|
||||
.. _recursive-relationships:
|
||||
|
||||
To create a recursive relationship -- an object that has a many-to-one
|
||||
relationship with itself -- use ``models.ForeignKey('self',
|
||||
on_delete=models.CASCADE)``.
|
||||
|
||||
.. _lazy-relationships:
|
||||
|
||||
If you need to create a relationship on a model that has not yet been defined,
|
||||
you can use the name of the model, rather than the model object itself::
|
||||
which the model is related and the :attr:`~ForeignKey.on_delete` option::
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Car(models.Model):
|
||||
manufacturer = models.ForeignKey(
|
||||
"Manufacturer",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
# ...
|
||||
|
||||
|
||||
class Manufacturer(models.Model):
|
||||
# ...
|
||||
pass
|
||||
name = models.TextField()
|
||||
|
||||
Relationships defined this way on :ref:`abstract models
|
||||
<abstract-base-classes>` are resolved when the model is subclassed as a
|
||||
concrete model and are not relative to the abstract model's ``app_label``:
|
||||
|
||||
.. code-block:: python
|
||||
:caption: ``products/models.py``
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class AbstractCar(models.Model):
|
||||
manufacturer = models.ForeignKey("Manufacturer", on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
.. code-block:: python
|
||||
:caption: ``production/models.py``
|
||||
|
||||
from django.db import models
|
||||
from products.models import AbstractCar
|
||||
|
||||
|
||||
class Manufacturer(models.Model):
|
||||
pass
|
||||
|
||||
|
||||
class Car(AbstractCar):
|
||||
pass
|
||||
|
||||
|
||||
# Car.manufacturer will point to `production.Manufacturer` here.
|
||||
|
||||
To refer to models defined in another application, you can explicitly specify
|
||||
a model with the full application label. For example, if the ``Manufacturer``
|
||||
model above is defined in another application called ``production``, you'd
|
||||
need to use::
|
||||
|
||||
class Car(models.Model):
|
||||
manufacturer = models.ForeignKey(
|
||||
"production.Manufacturer",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
|
||||
|
||||
This sort of reference, called a lazy relationship, can be useful when
|
||||
resolving circular import dependencies between two applications.
|
||||
The first positional argument can be either a concrete model class or a
|
||||
:ref:`lazy reference <lazy-relationships>` to a model class.
|
||||
:ref:`Recursive relationships <recursive-relationships>`, where a model has a
|
||||
relationship with itself, are also supported.
|
||||
|
||||
See :attr:`ForeignKey.on_delete` for details on the second positional
|
||||
argument.
|
||||
|
||||
A database index is automatically created on the ``ForeignKey``. You can
|
||||
disable this by setting :attr:`~Field.db_index` to ``False``. You may want to
|
||||
@@ -1714,9 +1664,9 @@ Database Representation
|
||||
|
||||
Behind the scenes, Django appends ``"_id"`` to the field name to create its
|
||||
database column name. In the above example, the database table for the ``Car``
|
||||
model will have a ``manufacturer_id`` column. (You can change this explicitly by
|
||||
specifying :attr:`~Field.db_column`) However, your code should never have to
|
||||
deal with the database column name, unless you write custom SQL. You'll always
|
||||
model will have a ``manufacturer_id`` column. You can change this explicitly by
|
||||
specifying :attr:`~Field.db_column`, however, your code should never have to
|
||||
deal with the database column name (unless you write custom SQL). You'll always
|
||||
deal with the field names of your model object.
|
||||
|
||||
.. _foreign-key-arguments:
|
||||
@@ -2266,6 +2216,120 @@ accepted by :class:`ForeignKey`, plus one extra argument:
|
||||
See :doc:`One-to-one relationships </topics/db/examples/one_to_one>` for usage
|
||||
examples of ``OneToOneField``.
|
||||
|
||||
.. _lazy-relationships:
|
||||
|
||||
Lazy relationships
|
||||
------------------
|
||||
|
||||
Lazy relationships allow referencing models by their names (as strings) or
|
||||
creating recursive relationships. Strings can be used as the first argument in
|
||||
any relationship field to reference models lazily. A lazy reference can be
|
||||
either :ref:`recursive <recursive-relationships>`,
|
||||
:ref:`relative <relative-relationships>` or
|
||||
:ref:`absolute <absolute-relationships>`.
|
||||
|
||||
.. _recursive-relationships:
|
||||
|
||||
Recursive
|
||||
~~~~~~~~~
|
||||
|
||||
To define a relationship where a model references itself, use ``"self"`` as the
|
||||
first argument of the relationship field::
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Manufacturer(models.Model):
|
||||
name = models.TextField()
|
||||
suppliers = models.ManyToManyField("self", symmetrical=False)
|
||||
|
||||
|
||||
When used in an :ref:`abstract model <abstract-base-classes>`, the recursive
|
||||
relationship resolves such that each concrete subclass references itself.
|
||||
|
||||
.. _relative-relationships:
|
||||
|
||||
Relative
|
||||
~~~~~~~~
|
||||
|
||||
When a relationship needs to be created with a model that has not been defined
|
||||
yet, it can be referenced by its name rather than the model object itself::
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Car(models.Model):
|
||||
manufacturer = models.ForeignKey(
|
||||
"Manufacturer",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
|
||||
class Manufacturer(models.Model):
|
||||
name = models.TextField()
|
||||
suppliers = models.ManyToManyField("self", symmetrical=False)
|
||||
|
||||
Relationships defined this way on :ref:`abstract models
|
||||
<abstract-base-classes>` are resolved when the model is subclassed as a
|
||||
concrete model and are not relative to the abstract model's ``app_label``:
|
||||
|
||||
.. code-block:: python
|
||||
:caption: ``products/models.py``
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class AbstractCar(models.Model):
|
||||
manufacturer = models.ForeignKey("Manufacturer", on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
.. code-block:: python
|
||||
:caption: ``production/models.py``
|
||||
|
||||
from django.db import models
|
||||
from products.models import AbstractCar
|
||||
|
||||
|
||||
class Manufacturer(models.Model):
|
||||
name = models.TextField()
|
||||
|
||||
|
||||
class Car(AbstractCar):
|
||||
pass
|
||||
|
||||
In this example, the ``Car.manufacturer`` relationship will resolve to
|
||||
``production.Manufacturer``, as it points to the concrete model defined
|
||||
within the ``production/models.py`` file.
|
||||
|
||||
.. admonition:: Reusable models with relative references
|
||||
|
||||
Relative references allow the creation of reusable abstract models with
|
||||
relationships that can resolve to different implementations of the
|
||||
referenced models in various subclasses across different applications.
|
||||
|
||||
.. _absolute-relationships:
|
||||
|
||||
Absolute
|
||||
~~~~~~~~
|
||||
|
||||
Absolute references specify a model using its ``app_label`` and class name,
|
||||
allowing for model references across different applications. This type of lazy
|
||||
relationship can also help resolve circular imports.
|
||||
|
||||
For example, if the ``Manufacturer`` model is defined in another application
|
||||
called ``thirdpartyapp``, it can be referenced as::
|
||||
|
||||
class Car(models.Model):
|
||||
manufacturer = models.ForeignKey(
|
||||
"thirdpartyapp.Manufacturer",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
Absolute references always point to the same model, even when used in an
|
||||
:ref:`abstract model <abstract-base-classes>`.
|
||||
|
||||
Field API reference
|
||||
===================
|
||||
|
||||
|
||||
@@ -3110,6 +3110,11 @@ there are triggers or if a function is called, even for a ``SELECT`` query.
|
||||
|
||||
Support for the ``generic_plan`` option on PostgreSQL 16+ was added.
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
Support for the ``memory`` and ``serialize`` options on PostgreSQL 17+ was
|
||||
added.
|
||||
|
||||
.. _field-lookups:
|
||||
|
||||
``Field`` lookups
|
||||
|
||||
@@ -833,6 +833,13 @@ Attributes
|
||||
|
||||
A bytestring representing the content, encoded from a string if necessary.
|
||||
|
||||
.. attribute:: HttpResponse.text
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
A string representation of :attr:`HttpResponse.content`, decoded using the
|
||||
response's :attr:`HttpResponse.charset` (defaulting to ``UTF-8`` if empty).
|
||||
|
||||
.. attribute:: HttpResponse.cookies
|
||||
|
||||
A :py:obj:`http.cookies.SimpleCookie` object holding the cookies included
|
||||
@@ -1272,6 +1279,9 @@ with the following notable differences:
|
||||
:attr:`~StreamingHttpResponse.streaming_content` attribute. This can be used
|
||||
in middleware to wrap the response iterable, but should not be consumed.
|
||||
|
||||
* It has no ``text`` attribute, as it would require iterating the response
|
||||
object.
|
||||
|
||||
* You cannot use the file-like object ``tell()`` or ``write()`` methods.
|
||||
Doing so will raise an exception.
|
||||
|
||||
|
||||
@@ -3100,7 +3100,7 @@ slightly different call:
|
||||
|
||||
{% load static %}
|
||||
{% static "images/hi.jpg" as myphoto %}
|
||||
<img src="{{ myphoto }}">
|
||||
<img src="{{ myphoto }}" alt="Hi!">
|
||||
|
||||
.. admonition:: Using Jinja2 templates?
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ your code, Django provides the following function:
|
||||
.. function:: reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
|
||||
|
||||
``viewname`` can be a :ref:`URL pattern name <naming-url-patterns>` or the
|
||||
callable view object. For example, given the following ``url``::
|
||||
callable view object used in the URLconf. For example, given the following
|
||||
``url``::
|
||||
|
||||
from news import views
|
||||
|
||||
@@ -79,6 +80,26 @@ use for reversing. By default, the root URLconf for the current thread is used.
|
||||
Applying further encoding (such as :func:`urllib.parse.quote`) to the output
|
||||
of ``reverse()`` may produce undesirable results.
|
||||
|
||||
.. admonition:: Reversing class-based views by view object
|
||||
|
||||
The view object can also be the result of calling
|
||||
:meth:`~django.views.generic.base.View.as_view` if the same view object is
|
||||
used in the URLConf. Following the original example, the view object could
|
||||
be defined as:
|
||||
|
||||
.. code-block:: python
|
||||
:caption: ``news/views.py``
|
||||
|
||||
from django.views import View
|
||||
|
||||
|
||||
class ArchiveView(View): ...
|
||||
|
||||
|
||||
archive = ArchiveView.as_view()
|
||||
|
||||
However, remember that namespaced views cannot be reversed by view object.
|
||||
|
||||
``reverse_lazy()``
|
||||
==================
|
||||
|
||||
|
||||
@@ -10,4 +10,13 @@ Django 5.1.3 fixes several bugs in 5.1.2 and adds compatibility with Python
|
||||
Bugfixes
|
||||
========
|
||||
|
||||
* ...
|
||||
* Fixed a bug in Django 5.1 where
|
||||
:class:`~django.core.validators.DomainNameValidator` accepted any input value
|
||||
that contained a valid domain name, rather than only input values that were a
|
||||
valid domain name (:ticket:`35845`).
|
||||
|
||||
* Fixed a regression in Django 5.1 that prevented the use of DB-IP databases
|
||||
with :class:`~django.contrib.gis.geoip2.GeoIP2` (:ticket:`35841`).
|
||||
|
||||
* Fixed a regression in Django 5.1 where non-ASCII fieldset names were not
|
||||
displayed when rendering admin fieldsets (:ticket:`35876`).
|
||||
|
||||
@@ -52,29 +52,29 @@ Minor features
|
||||
* The default iteration count for the PBKDF2 password hasher is increased from
|
||||
870,000 to 1,000,000.
|
||||
|
||||
* The following new asynchronous methods on are now provided, using an ``a``
|
||||
* The following new asynchronous methods are now provided, using an ``a``
|
||||
prefix:
|
||||
|
||||
* :meth:`.UserManager.acreate_user`
|
||||
* :meth:`.UserManager.acreate_superuser`
|
||||
* :meth:`.BaseUserManager.aget_by_natural_key`
|
||||
* :meth:`.User.aget_user_permissions()`
|
||||
* :meth:`.User.aget_all_permissions()`
|
||||
* :meth:`.User.aget_group_permissions()`
|
||||
* :meth:`.User.ahas_perm()`
|
||||
* :meth:`.User.ahas_perms()`
|
||||
* :meth:`.User.ahas_module_perms()`
|
||||
* :meth:`.User.aget_user_permissions()`
|
||||
* :meth:`.User.aget_group_permissions()`
|
||||
* :meth:`.User.ahas_perm()`
|
||||
* :meth:`.ModelBackend.aauthenticate()`
|
||||
* :meth:`.ModelBackend.aget_user_permissions()`
|
||||
* :meth:`.ModelBackend.aget_group_permissions()`
|
||||
* :meth:`.ModelBackend.aget_all_permissions()`
|
||||
* :meth:`.ModelBackend.ahas_perm()`
|
||||
* :meth:`.ModelBackend.ahas_module_perms()`
|
||||
* :meth:`.RemoteUserBackend.aauthenticate()`
|
||||
* :meth:`.RemoteUserBackend.aconfigure_user()`
|
||||
* :meth:`.User.aget_user_permissions`
|
||||
* :meth:`.User.aget_all_permissions`
|
||||
* :meth:`.User.aget_group_permissions`
|
||||
* :meth:`.User.ahas_perm`
|
||||
* :meth:`.User.ahas_perms`
|
||||
* :meth:`.User.ahas_module_perms`
|
||||
* :meth:`.User.aget_user_permissions`
|
||||
* :meth:`.User.aget_group_permissions`
|
||||
* :meth:`.User.ahas_perm`
|
||||
* :meth:`.ModelBackend.aauthenticate`
|
||||
* :meth:`.ModelBackend.aget_user_permissions`
|
||||
* :meth:`.ModelBackend.aget_group_permissions`
|
||||
* :meth:`.ModelBackend.aget_all_permissions`
|
||||
* :meth:`.ModelBackend.ahas_perm`
|
||||
* :meth:`.ModelBackend.ahas_module_perms`
|
||||
* :meth:`.RemoteUserBackend.aauthenticate`
|
||||
* :meth:`.RemoteUserBackend.aconfigure_user`
|
||||
|
||||
* Auth backends can now provide async implementations which are used when
|
||||
calling async auth functions (e.g.
|
||||
@@ -82,6 +82,10 @@ Minor features
|
||||
improves performance. See :ref:`adding an async interface
|
||||
<writing-authentication-backends-async-interface>` for more details.
|
||||
|
||||
* The :ref:`password validator classes <included-password-validators>`
|
||||
now have a new method ``get_error_message()``, which can be overridden in
|
||||
subclasses to customize the error messages.
|
||||
|
||||
:mod:`django.contrib.contenttypes`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -90,7 +94,19 @@ Minor features
|
||||
:mod:`django.contrib.gis`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* GDAL now supports curved geometries ``CurvePolygon``, ``CompoundCurve``,
|
||||
``CircularString``, ``MultiSurface``, and ``MultiCurve`` via the new
|
||||
:attr:`.OGRGeometry.has_curve` property, and the
|
||||
:meth:`.OGRGeometry.get_linear_geometry` and
|
||||
:meth:`.OGRGeometry.get_curve_geometry` methods.
|
||||
|
||||
* :lookup:`coveredby` and :lookup:`covers` lookup are now supported on MySQL.
|
||||
|
||||
* :lookup:`coveredby` and :lookup:`isvalid` lookups,
|
||||
:class:`~django.contrib.gis.db.models.Collect` aggregation, and
|
||||
:class:`~django.contrib.gis.db.models.functions.GeoHash` and
|
||||
:class:`~django.contrib.gis.db.models.functions.IsValid` database functions
|
||||
are now supported on MariaDB 11.7+.
|
||||
|
||||
:mod:`django.contrib.messages`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -230,6 +246,10 @@ Management Commands
|
||||
setting the :envvar:`HIDE_PRODUCTION_WARNING` environment variable to
|
||||
``"true"``.
|
||||
|
||||
* The :djadmin:`makemigrations` and :djadmin:`migrate` commands have a new
|
||||
``Command.autodetector`` attribute for subclasses to override in order to use
|
||||
a custom autodetector class.
|
||||
|
||||
Migrations
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -257,9 +277,15 @@ Models
|
||||
longer required to be set on SQLite, which supports unlimited ``VARCHAR``
|
||||
columns.
|
||||
|
||||
* :meth:`.QuerySet.explain` now supports the ``memory`` and ``serialize``
|
||||
options on PostgreSQL 17+.
|
||||
|
||||
Requests and Responses
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* The new :attr:`.HttpResponse.text` property provides the string representation
|
||||
of :attr:`.HttpResponse.content`.
|
||||
|
||||
* The new :meth:`.HttpRequest.get_preferred_type` method can be used to query
|
||||
the preferred media type the client accepts.
|
||||
|
||||
@@ -358,6 +384,11 @@ Miscellaneous
|
||||
* ``HttpRequest.accepted_types`` is now sorted by the client's preference, based
|
||||
on the request's ``Accept`` header.
|
||||
|
||||
* :attr:`.UniqueConstraint.violation_error_code` and
|
||||
:attr:`.UniqueConstraint.violation_error_message` are now always used when
|
||||
provided. Previously, these were ignored when :attr:`.UniqueConstraint.fields`
|
||||
were set without a :attr:`.UniqueConstraint.condition`.
|
||||
|
||||
* The :func:`~django.template.context_processors.debug` context processor is no
|
||||
longer included in the default project template.
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ deduplicates
|
||||
deduplication
|
||||
deepcopy
|
||||
deferrable
|
||||
DEP
|
||||
deprecations
|
||||
deserialization
|
||||
deserialize
|
||||
|
||||
@@ -590,6 +590,8 @@ has no settings.
|
||||
The help texts and any errors from password validators are always returned in
|
||||
the order they are listed in :setting:`AUTH_PASSWORD_VALIDATORS`.
|
||||
|
||||
.. _included-password-validators:
|
||||
|
||||
Included validators
|
||||
-------------------
|
||||
|
||||
@@ -600,6 +602,19 @@ Django includes four validators:
|
||||
Validates that the password is of a minimum length.
|
||||
The minimum length can be customized with the ``min_length`` parameter.
|
||||
|
||||
.. method:: get_error_message()
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
A hook for customizing the ``ValidationError`` error message. Defaults
|
||||
to ``"This password is too short. It must contain at least <min_length>
|
||||
characters."``.
|
||||
|
||||
.. method:: get_help_text()
|
||||
|
||||
A hook for customizing the validator's help text. Defaults to ``"Your
|
||||
password must contain at least <min_length> characters."``.
|
||||
|
||||
.. class:: UserAttributeSimilarityValidator(user_attributes=DEFAULT_USER_ATTRIBUTES, max_similarity=0.7)
|
||||
|
||||
Validates that the password is sufficiently different from certain
|
||||
@@ -617,6 +632,18 @@ Django includes four validators:
|
||||
``user_attributes``, whereas a value of 1.0 rejects only passwords that are
|
||||
identical to an attribute's value.
|
||||
|
||||
.. method:: get_error_message()
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
A hook for customizing the ``ValidationError`` error message. Defaults
|
||||
to ``"The password is too similar to the <user_attribute>."``.
|
||||
|
||||
.. method:: get_help_text()
|
||||
|
||||
A hook for customizing the validator's help text. Defaults to ``"Your
|
||||
password can’t be too similar to your other personal information."``.
|
||||
|
||||
.. class:: CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH)
|
||||
|
||||
Validates that the password is not a common password. This converts the
|
||||
@@ -628,10 +655,34 @@ Django includes four validators:
|
||||
common passwords. This file should contain one lowercase password per line
|
||||
and may be plain text or gzipped.
|
||||
|
||||
.. method:: get_error_message()
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
A hook for customizing the ``ValidationError`` error message. Defaults
|
||||
to ``"This password is too common."``.
|
||||
|
||||
.. method:: get_help_text()
|
||||
|
||||
A hook for customizing the validator's help text. Defaults to ``"Your
|
||||
password can’t be a commonly used password."``.
|
||||
|
||||
.. class:: NumericPasswordValidator()
|
||||
|
||||
Validate that the password is not entirely numeric.
|
||||
|
||||
.. method:: get_error_message()
|
||||
|
||||
.. versionadded:: 5.2
|
||||
|
||||
A hook for customizing the ``ValidationError`` error message. Defaults
|
||||
to ``"This password is entirely numeric."``.
|
||||
|
||||
.. method:: get_help_text()
|
||||
|
||||
A hook for customizing the validator's help text. Defaults to ``"Your
|
||||
password can’t be entirely numeric."``.
|
||||
|
||||
Integrating validation
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -224,6 +224,15 @@ ones:
|
||||
object. If callable it will be called every time a new object is
|
||||
created.
|
||||
|
||||
:attr:`~Field.db_default`
|
||||
The database-computed default value for the field. This can be a literal
|
||||
value or a database function.
|
||||
|
||||
If both ``db_default`` and :attr:`Field.default` are set, ``default`` will
|
||||
take precedence when creating instances in Python code. ``db_default`` will
|
||||
still be set at the database level and will be used when inserting rows
|
||||
outside of the ORM or when adding a new field in a migration.
|
||||
|
||||
:attr:`~Field.help_text`
|
||||
Extra "help" text to be displayed with the form widget. It's useful for
|
||||
documentation even if your field isn't used on a form.
|
||||
|
||||
@@ -311,9 +311,11 @@ All parameters are optional and can be set at any time prior to calling the
|
||||
* ``bcc``: A list or tuple of addresses used in the "Bcc" header when
|
||||
sending the email.
|
||||
|
||||
* ``connection``: An email backend instance. Use this parameter if
|
||||
you want to use the same connection for multiple messages. If omitted, a
|
||||
new connection is created when ``send()`` is called.
|
||||
* ``connection``: An :ref:`email backend <topic-email-backends>` instance. Use
|
||||
this parameter if you are sending the ``EmailMessage`` via ``send()`` and you
|
||||
want to use the same connection for multiple messages. If omitted, a new
|
||||
connection is created when ``send()`` is called. This parameter is ignored
|
||||
when using :ref:`send_messages() <topics-sending-multiple-emails>`.
|
||||
|
||||
* ``attachments``: A list of attachments to put on the message. These can
|
||||
be instances of :class:`~email.mime.base.MIMEBase` or
|
||||
@@ -728,9 +730,10 @@ destroying a connection every time you want to send an email.
|
||||
|
||||
There are two ways you tell an email backend to reuse a connection.
|
||||
|
||||
Firstly, you can use the ``send_messages()`` method. ``send_messages()`` takes
|
||||
a list of :class:`~django.core.mail.EmailMessage` instances (or subclasses),
|
||||
and sends them all using a single connection.
|
||||
Firstly, you can use the ``send_messages()`` method on a connection. This takes
|
||||
a list of :class:`EmailMessage` (or subclass) instances, and sends them all
|
||||
using that single connection. As a consequence, any :class:`connection
|
||||
<EmailMessage>` set on an individual message is ignored.
|
||||
|
||||
For example, if you have a function called ``get_notification_email()`` that
|
||||
returns a list of :class:`~django.core.mail.EmailMessage` objects representing
|
||||
|
||||
@@ -23,7 +23,7 @@ Here's a view that returns the current date and time, as an HTML document::
|
||||
|
||||
def current_datetime(request):
|
||||
now = datetime.datetime.now()
|
||||
html = "<html><body>It is now %s.</body></html>" % now
|
||||
html = '<html lang="en"><body>It is now %s.</body></html>' % now
|
||||
return HttpResponse(html)
|
||||
|
||||
Let's step through this code one line at a time:
|
||||
@@ -225,7 +225,7 @@ Here's an example of an async view::
|
||||
|
||||
async def current_datetime(request):
|
||||
now = datetime.datetime.now()
|
||||
html = "<html><body>It is now %s.</body></html>" % now
|
||||
html = '<html lang="en"><body>It is now %s.</body></html>' % now
|
||||
return HttpResponse(html)
|
||||
|
||||
You can read more about Django's async support, and how to best use async
|
||||
|
||||
Reference in New Issue
Block a user