1
0
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:
Mariana
2024-10-09 15:39:13 +01:00
committed by GitHub
613 changed files with 13617 additions and 5301 deletions

View File

@@ -94,7 +94,7 @@ spelling_warning = True
# templates_path = []
# The suffix of source filenames.
source_suffix = ".txt"
source_suffix = {".txt": "restructuredtext"}
# The encoding of source files.
# source_encoding = 'utf-8-sig'
@@ -182,9 +182,9 @@ pygments_style = "trac"
# Links to Python's docs should reference the most recent version of the 3.x
# branch, which is located at this URL.
intersphinx_mapping = {
"python": ("https://docs.python.org/3/", None),
"sphinx": ("https://www.sphinx-doc.org/en/master/", None),
"psycopg": ("https://www.psycopg.org/psycopg3/docs/", None),
"python": ("https://docs.python.org/3", None),
"sphinx": ("https://www.sphinx-doc.org/en/master", None),
"psycopg": ("https://www.psycopg.org/psycopg3/docs", None),
}
# Python's docs don't change every week.
@@ -292,8 +292,12 @@ latex_elements = {
\setmainfont{Symbola}
""",
"preamble": r"""
\usepackage{newunicodechar}
\usepackage[UTF8]{ctex}
\xeCJKDeclareCharClass{HalfLeft}{"2018, "201C}
\xeCJKDeclareCharClass{HalfRight}{
"00B7, "2019, "201D, "2013, "2014, "2025, "2026, "2E3A
}
\usepackage{newunicodechar}
\newunicodechar{π}{\ensuremath{\pi}}
\newunicodechar{≤}{\ensuremath{\le}}
\newunicodechar{≥}{\ensuremath{\ge}}

View File

@@ -52,7 +52,7 @@ Django version Python versions
============== ===============
4.2 3.8, 3.9, 3.10, 3.11, 3.12 (added in 4.2.8)
5.0 3.10, 3.11, 3.12
5.1 3.10, 3.11, 3.12
5.1 3.10, 3.11, 3.12, 3.13 (added in 5.1.3)
5.2 3.10, 3.11, 3.12, 3.13
============== ===============

View File

@@ -645,6 +645,9 @@ delegate further handling to the parent class. This might require you to write
a custom form field (and even a form widget). See the :doc:`forms documentation
</topics/forms/index>` for information about this.
If you wish to exclude the field from the :class:`~django.forms.ModelForm`, you
can override the :meth:`~Field.formfield` method to return ``None``.
Continuing our ongoing example, we can write the :meth:`~Field.formfield` method
as::
@@ -652,8 +655,12 @@ as::
# ...
def formfield(self, **kwargs):
# This is a fairly standard way to set up some defaults
# while letting the caller override them.
# Exclude the field from the ModelForm when some condition is met.
some_condition = kwargs.get("some_condition", False)
if some_condition:
return None
# Set up some defaults while letting the caller override them.
defaults = {"form_class": MyFormField}
defaults.update(kwargs)
return super().formfield(**defaults)

View File

@@ -154,7 +154,8 @@ Origin API and 3rd-party integration
Django templates have an :class:`~django.template.base.Origin` object available
through the ``template.origin`` attribute. This enables debug information to be
displayed in the :ref:`template postmortem <template-postmortem>`, as well as
in 3rd-party libraries, like the `Django Debug Toolbar`_.
in 3rd-party libraries, like the :pypi:`Django Debug Toolbar
<django-debug-toolbar>`.
Custom engines can provide their own ``template.origin`` information by
creating an object that specifies the following attributes:
@@ -168,4 +169,3 @@ creating an object that specifies the following attributes:
to load the template, e.g. ``django.template.loaders.filesystem.Loader``.
.. _DEP 182: https://github.com/django/deps/blob/main/final/0182-multiple-template-engines.rst
.. _Django Debug Toolbar: https://github.com/jazzband/django-debug-toolbar/

View File

@@ -47,13 +47,13 @@ To install Uvicorn and Gunicorn, use the following:
.. code-block:: shell
python -m pip install uvicorn gunicorn
python -m pip install uvicorn uvicorn-worker gunicorn
Then start Gunicorn using the Uvicorn worker class like this:
.. code-block:: shell
python -m gunicorn myproject.asgi:application -k uvicorn.workers.UvicornWorker
python -m gunicorn myproject.asgi:application -k uvicorn_worker.UvicornWorker
.. _Uvicorn: https://www.uvicorn.org/
.. _Gunicorn: https://gunicorn.org/

View File

@@ -36,6 +36,14 @@ Some of the checks described below can be automated using the :option:`check
--deploy` option. Be sure to run it against your production settings file as
described in the option's documentation.
Switch away from ``manage.py runserver``
========================================
The :djadmin:`runserver` command is not designed for a production setting. Be
sure to switch to a production-ready WSGI or ASGI server. For a few common
options, see :doc:`WSGI servers </howto/deployment/wsgi/index>` or
:doc:`ASGI servers </howto/deployment/asgi/index>`.
Critical settings
=================

View File

@@ -12,7 +12,8 @@ the scope of what Django can give you as guidance.
Django, being a web framework, needs a web server in order to operate. And
since most web servers don't natively speak Python, we need an interface to
make that communication happen.
make that communication happen. The :djadmin:`runserver` command starts a
lightweight development server, which is not suitable for production.
Django currently supports two interfaces: WSGI and ASGI.

View File

@@ -282,7 +282,11 @@ following attributes and methods:
import re
re.compile(r"API|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)
re.compile(r"API|AUTH|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)
.. versionchanged:: 5.2
The term ``AUTH`` was added.
.. method:: is_active(request)

View File

@@ -85,7 +85,7 @@ Tell Django where to look for fixture files
-------------------------------------------
By default, Django looks for fixtures in the ``fixtures`` directory inside each
app for, so the command ``loaddata sample`` will find the file
app, so the command ``loaddata sample`` will find the file
``my_app/fixtures/sample.json``. This works with relative paths as well, so
``loaddata my_app/sample`` will find the file
``my_app/fixtures/my_app/sample.json``.
@@ -93,7 +93,7 @@ app for, so the command ``loaddata sample`` will find the file
Django also looks for fixtures in the list of directories provided in the
:setting:`FIXTURE_DIRS` setting.
To completely prevent default search form happening, use an absolute path to
To completely prevent default search from happening, use an absolute path to
specify the location of your fixture file, e.g. ``loaddata /path/to/sample``.
.. admonition:: Namespace your fixture files

View File

@@ -2,7 +2,7 @@
How to install Django on Windows
================================
This document will guide you through installing Python 3.12 and Django on
This document will guide you through installing Python 3.13 and Django on
Windows. It also provides instructions for setting up a virtual environment,
which makes it easier to work on Python projects. This is meant as a beginner's
guide for users working on Django projects and does not reflect how Django
@@ -18,7 +18,7 @@ Install Python
==============
Django is a Python web framework, thus requiring Python to be installed on your
machine. At the time of writing, Python 3.12 is the latest version.
machine. At the time of writing, Python 3.13 is the latest version.
To install Python on your machine go to https://www.python.org/downloads/. The
website should offer you a download button for the latest Python version.

View File

@@ -110,13 +110,17 @@ part of that. Here are some tips on how to make a request most effectively:
If there's a consensus agreement on the feature, then it's appropriate to
create a ticket. Include a link to the discussion in the ticket description.
As with most open-source projects, code talks. If you are willing to write the
code for the feature yourself or, even better, if you've already written it,
it's much more likely to be accepted. Fork Django on GitHub, create a feature
branch, and show us your work!
See also: :ref:`documenting-new-features`.
Requesting performance optimizations
====================================
Reports of a performance regression, or suggested performance optimizations,
should provide benchmarks and commands for the ticket triager to reproduce.
See the :ref:`django-asv-benchmarks` for more details of Django's existing
benchmarks.
.. _how-we-make-decisions:
How we make decisions

View File

@@ -35,8 +35,8 @@ with them.
Python style
============
* All files should be formatted using the `black`_ auto-formatter. This will be
run by ``pre-commit`` if that is configured.
* All files should be formatted using the :pypi:`black` auto-formatter. This
will be run by ``pre-commit`` if that is configured.
* The project repository includes an ``.editorconfig`` file. We recommend using
a text editor with `EditorConfig`_ support to avoid indentation and
@@ -506,5 +506,4 @@ JavaScript style
For details about the JavaScript code style used by Django, see
:doc:`javascript`.
.. _black: https://black.readthedocs.io/en/stable/
.. _editorconfig: https://editorconfig.org/

View File

@@ -6,6 +6,8 @@ We're always grateful for contributions to Django's code. Indeed, bug reports
with associated contributions will get fixed *far* more quickly than those
without a solution.
.. _trivial-change:
Typo fixes and trivial documentation changes
============================================
@@ -52,9 +54,10 @@ and time availability), claim it by following these steps:
.. note::
The Django software foundation requests that anyone contributing more than
a trivial change to Django sign and submit a `Contributor License
Agreement`_, this ensures that the Django Software Foundation has clear
license to all contributions allowing for a clear license for all users.
a :ref:`trivial change <trivial-change>`, to Django sign and submit a
`Contributor License Agreement`_, this ensures that the Django Software
Foundation has clear license to all contributions allowing for a clear
license for all users.
.. _Login using your GitHub account: https://code.djangoproject.com/github/login
.. _Create an account: https://www.djangoproject.com/accounts/register/
@@ -206,9 +209,10 @@ You should also add a test for the deprecation warning::
def test_foo_deprecation_warning(self):
msg = "Expected deprecation message"
with self.assertWarnsMessage(RemovedInDjangoXXWarning, msg):
with self.assertWarnsMessage(RemovedInDjangoXXWarning, msg) as ctx:
# invoke deprecated behavior
...
self.assertEqual(ctx.filename, __file__)
It's important to include a ``RemovedInDjangoXXWarning`` comment above code
which has no warning reference, but will need to be changed or removed when the
@@ -230,6 +234,7 @@ deprecation ends. For example::
warnings.warn(
"foo() is deprecated.",
category=RemovedInDjangoXXWarning,
stacklevel=2,
)
old_private_helper()
...
@@ -257,21 +262,45 @@ JavaScript contributions
For information on JavaScript contributions, see the :ref:`javascript-patches`
documentation.
Optimization patches
====================
Patches aiming to deliver a performance improvement should provide benchmarks
showing the before and after impact of the patch and sharing the commands for
reviewers to reproduce.
.. _django-asv-benchmarks:
``django-asv`` benchmarks
-------------------------
`django-asv`_ monitors the performance of Django code over time. These
benchmarks can be run on a pull request by labeling the pull request with
``benchmark``. Adding to these benchmarks is highly encouraged.
.. _django-asv: https://github.com/django/django-asv/
.. _patch-review-checklist:
Contribution checklist
======================
Use this checklist to review a pull request. If you are reviewing a pull
request that is not your own and it passes all the criteria below, please set
the "Triage Stage" on the corresponding Trac ticket to "Ready for checkin".
Use this checklist to review a pull request. If this contribution would not be
:ref:`considered trivial <trivial-change>`, first ensure it has an accepted
ticket before proceeding with the review.
If the pull request passes all the criteria below and is not your own, please
set the "Triage Stage" on the corresponding Trac ticket to "Ready for checkin".
If you've left comments for improvement on the pull request, please tick the
appropriate flags on the Trac ticket based on the results of your review:
"Patch needs improvement", "Needs documentation", and/or "Needs tests". As time
and interest permits, mergers do final reviews of "Ready for checkin" tickets
and will either commit the changes or bump it back to "Accepted" if further
work needs to be done. If you're looking to become a merger, doing thorough
reviews of contributions is a great way to earn trust.
work needs to be done.
If you're looking to become a member of the `triage & review team
<https://www.djangoproject.com/foundation/teams/#triage-review-team>`_, doing
thorough reviews of contributions is a great way to earn trust.
Looking for a patch to review? Check out the "Patches needing review" section
of the `Django Development Dashboard <https://dashboard.djangoproject.com/>`_.
@@ -331,5 +360,7 @@ All tickets
:ref:`commit message format <committing-guidelines>`?
* Are you the patch author and a new contributor? Please add yourself to the
:source:`AUTHORS` file and submit a `Contributor License Agreement`_.
* Does this have an accepted ticket on Trac? All contributions require a ticket
unless the :ref:`change is considered trivial <trivial-change>`.
.. _Contributor License Agreement: https://www.djangoproject.com/foundation/cla/

View File

@@ -313,7 +313,7 @@ dependencies:
* :pypi:`aiosmtpd`
* :pypi:`argon2-cffi` 19.2.0+
* :pypi:`asgiref` 3.7.0+ (required)
* :pypi:`asgiref` 3.8.1+ (required)
* :pypi:`bcrypt`
* :pypi:`colorama` 0.4.6+
* :pypi:`docutils` 0.19+

View File

@@ -169,7 +169,7 @@ The steering council is a group of experienced contributors who:
- provide oversight of Django's development and release process,
- assist in setting the direction of feature development and releases,
- take part in filling certain roles, and
- select Mergers and Releasers, and
- have a tie-breaking vote when other decision-making processes fail.
Their main concern is to maintain the quality and stability of the Django Web
@@ -186,7 +186,6 @@ The steering council holds the following prerogatives:
the reversion of any particular merge or commit.
- Announcing calls for proposals and ideas for the future technical direction
of Django.
- Setting and adjusting the schedule of releases of Django.
- Selecting and removing mergers and releasers.
- Participating in the removal of members of the steering council, when deemed
appropriate.
@@ -211,10 +210,13 @@ who demonstrate:
This history must begin at least 18 months prior to the individual's
candidacy for the Steering Council, and include substantive contributions in
at least two of these bullet points:
- Code contributions on Django projects or major third-party packages in the Django ecosystem
- Code contributions to Django projects or major third-party packages in the
Django ecosystem
- Reviewing pull requests and/or triaging Django project tickets
- Documentation, tutorials or blog posts
- Discussions about Django on the django-developers mailing list or the Django Forum
- Discussions about Django on the django-developers mailing list or the Django
Forum
- Running Django-related events or user groups
- A history of engagement with the direction and future of Django. This does

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -26,7 +26,7 @@ representing your models -- so far, it's been solving many years' worth of
database-schema problems. Here's a quick example:
.. code-block:: python
:caption: ``mysite/news/models.py``
:caption: ``news/models.py``
from django.db import models
@@ -151,7 +151,7 @@ a website that lets authenticated users add, change and delete objects. The
only step required is to register your model in the admin site:
.. code-block:: python
:caption: ``mysite/news/models.py``
:caption: ``news/models.py``
from django.db import models
@@ -163,7 +163,7 @@ only step required is to register your model in the admin site:
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
.. code-block:: python
:caption: ``mysite/news/admin.py``
:caption: ``news/admin.py``
from django.contrib import admin
@@ -195,7 +195,7 @@ Here's what a URLconf might look like for the ``Reporter``/``Article``
example above:
.. code-block:: python
:caption: ``mysite/news/urls.py``
:caption: ``news/urls.py``
from django.urls import path
@@ -235,7 +235,7 @@ and renders the template with the retrieved data. Here's an example view for
``year_archive`` from above:
.. code-block:: python
:caption: ``mysite/news/views.py``
:caption: ``news/views.py``
from django.shortcuts import render
@@ -265,7 +265,7 @@ Let's say the ``news/year_archive.html`` template was found. Here's what that
might look like:
.. code-block:: html+django
:caption: ``mysite/news/templates/news/year_archive.html``
:caption: ``news/templates/news/year_archive.html``
{% extends "base.html" %}
@@ -306,7 +306,7 @@ Here's what the "base.html" template, including the use of :doc:`static files
</howto/static-files/index>`, might look like:
.. code-block:: html+django
:caption: ``mysite/templates/base.html``
:caption: ``templates/base.html``
{% load static %}
<html>

View File

@@ -57,7 +57,7 @@ After the previous tutorials, our project should look like this:
.. code-block:: text
mysite/
djangotutorial/
manage.py
mysite/
__init__.py
@@ -90,12 +90,12 @@ After the previous tutorials, our project should look like this:
admin/
base_site.html
You created ``mysite/templates`` in :doc:`Tutorial 7 </intro/tutorial07>`,
and ``polls/templates`` in :doc:`Tutorial 3 </intro/tutorial03>`. Now perhaps
it is clearer why we chose to have separate template directories for the
project and application: everything that is part of the polls application is in
``polls``. It makes the application self-contained and easier to drop into a
new project.
You created ``djangotutorial/templates`` in :doc:`Tutorial 7
</intro/tutorial07>`, and ``polls/templates`` in
:doc:`Tutorial 3 </intro/tutorial03>`. Now perhaps it is clearer why we chose
to have separate template directories for the project and application:
everything that is part of the polls application is in ``polls``. It makes the
application self-contained and easier to drop into a new project.
The ``polls`` directory could now be copied into a new Django project and
immediately reused. It's not quite ready to be published though. For that, we
@@ -237,6 +237,7 @@ this. For a small app like polls, this process isn't too difficult.
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
]

View File

@@ -48,14 +48,21 @@ including database configuration, Django-specific options and
application-specific settings.
From the command line, ``cd`` into a directory where you'd like to store your
code, then run the following command:
code and create a new directory named ``djangotutorial``. (This directory name
doesn't matter to Django; you can rename it to anything you like.)
.. console::
$ django-admin startproject mysite
$ mkdir djangotutorial
This will create a ``mysite`` directory in your current directory. If it didn't
work, see :ref:`troubleshooting-django-admin`.
Then, run the following command to bootstrap a new Django project:
.. console::
$ django-admin startproject mysite djangotutorial
This will create a project called ``mysite`` inside the ``djangotutorial``
directory. If it didn't work, see :ref:`troubleshooting-django-admin`.
.. note::
@@ -68,7 +75,7 @@ Let's look at what :djadmin:`startproject` created:
.. code-block:: text
mysite/
djangotutorial/
manage.py
mysite/
__init__.py
@@ -79,14 +86,11 @@ Let's look at what :djadmin:`startproject` created:
These files are:
* The outer :file:`mysite/` root directory is a container for your project. Its
name doesn't matter to Django; you can rename it to anything you like.
* :file:`manage.py`: A command-line utility that lets you interact with this
Django project in various ways. You can read all the details about
:file:`manage.py` in :doc:`/ref/django-admin`.
* The inner :file:`mysite/` directory is the actual Python package for your
* :file:`mysite/`: A directory that is the actual Python package for your
project. Its name is the Python package name you'll need to use to import
anything inside it (e.g. ``mysite.urls``).
@@ -111,8 +115,8 @@ These files are:
The development server
======================
Let's verify your Django project works. Change into the outer :file:`mysite` directory, if
you haven't already, and run the following commands:
Let's verify your Django project works. Change into the :file:`djangotutorial`
directory, if you haven't already, and run the following commands:
.. console::
@@ -134,6 +138,9 @@ You'll see the following output on the command line:
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
WARNING: This is a development server. Do not use it in a production setting. Use a production WSGI or ASGI server instead.
For more information on production servers see: https://docs.djangoproject.com/en/|version|/howto/deployment/
.. note::
Ignore the warning about unapplied database migrations for now; we'll deal
with the database shortly.
@@ -179,10 +186,8 @@ rather than creating directories.
configuration and apps for a particular website. A project can contain
multiple apps. An app can be in multiple projects.
Your apps can live anywhere on your :ref:`Python path <tut-searchpath>`. In
this tutorial, we'll create our poll app in the same directory as your
:file:`manage.py` file so that it can be imported as its own top-level module,
rather than a submodule of ``mysite``.
Your apps can live anywhere in your :ref:`Python path <tut-searchpath>`. In
this tutorial, we'll create our poll app inside the ``djangotutorial`` folder.
To create your app, make sure you're in the same directory as :file:`manage.py`
and type this command:
@@ -272,6 +277,8 @@ include the URLconf defined in ``polls.urls``. To do this, add an import for
path("admin/", admin.site.urls),
]
The :func:`~django.urls.path` function expects at least two arguments:
``route`` and ``view``.
The :func:`~django.urls.include` function allows referencing other URLconfs.
Whenever Django encounters :func:`~django.urls.include`, it chops off whatever
part of the URL matched up to that point and sends the remaining string to the
@@ -304,45 +311,6 @@ text "*Hello, world. You're at the polls index.*", which you defined in the
If you get an error page here, check that you're going to
http://localhost:8000/polls/ and not http://localhost:8000/.
The :func:`~django.urls.path` function is passed four arguments, two required:
``route`` and ``view``, and two optional: ``kwargs``, and ``name``.
At this point, it's worth reviewing what these arguments are for.
:func:`~django.urls.path` argument: ``route``
---------------------------------------------
``route`` is a string that contains a URL pattern. When processing a request,
Django starts at the first pattern in ``urlpatterns`` and makes its way down
the list, comparing the requested URL against each pattern until it finds one
that matches.
Patterns don't search GET and POST parameters, or the domain name. For example,
in a request to ``https://www.example.com/myapp/``, the URLconf will look for
``myapp/``. In a request to ``https://www.example.com/myapp/?page=3``, the
URLconf will also look for ``myapp/``.
:func:`~django.urls.path` argument: ``view``
--------------------------------------------
When Django finds a matching pattern, it calls the specified view function with
an :class:`~django.http.HttpRequest` object as the first argument and any
"captured" values from the route as keyword arguments. We'll give an example
of this in a bit.
:func:`~django.urls.path` argument: ``kwargs``
----------------------------------------------
Arbitrary keyword arguments can be passed in a dictionary to the target view. We
aren't going to use this feature of Django in the tutorial.
:func:`~django.urls.path` argument: ``name``
--------------------------------------------
Naming your URL lets you refer to it unambiguously from elsewhere in Django,
especially from within templates. This powerful feature allows you to make
global changes to the URL patterns of your project while only touching a single
file.
When you're comfortable with the basic request and response flow, read
:doc:`part 2 of this tutorial </intro/tutorial02>` to start working with the
database.

View File

@@ -216,7 +216,7 @@ and you'll see something like:
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionModelTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/path/to/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_question
File "/path/to/djangotutorial/polls/tests.py", line 16, in test_was_published_recently_with_future_question
self.assertIs(future_question.was_published_recently(), False)
AssertionError: True is not False

View File

@@ -232,7 +232,8 @@ underscores replaced with spaces), and that each line contains the string
representation of the output.
You can improve that by using the :func:`~django.contrib.admin.display`
decorator on that method (in :file:`polls/models.py`), as follows:
decorator on that method (extending the :file:`polls/models.py` file that was
created in :doc:`Tutorial 2 </intro/tutorial02>`), as follows:
.. code-block:: python
:caption: ``polls/models.py``
@@ -305,10 +306,10 @@ powered by Django itself, and its interfaces use Django's own template system.
Customizing your *project's* templates
--------------------------------------
Create a ``templates`` directory in your project directory (the one that
contains ``manage.py``). Templates can live anywhere on your filesystem that
Django can access. (Django runs as whatever user your server runs.) However,
keeping your templates within the project is a good convention to follow.
Create a ``templates`` directory in your ``djangotutorial`` directory.
Templates can live anywhere on your filesystem that Django can access. (Django
runs as whatever user your server runs.) However, keeping your templates within
the project is a good convention to follow.
Open your settings file (:file:`mysite/settings.py`, remember) and add a
:setting:`DIRS <TEMPLATES-DIRS>` option in the :setting:`TEMPLATES` setting:
@@ -323,7 +324,6 @@ Open your settings file (:file:`mysite/settings.py`, remember) and add a
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",

View File

@@ -8,10 +8,10 @@ Django's strengths is the rich ecosystem of third-party packages. They're
community developed packages that can be used to quickly improve the feature set
of an application.
This tutorial will show how to add `Django Debug Toolbar
<https://django-debug-toolbar.readthedocs.io>`_, a commonly used third-party
package. The Django Debug Toolbar has ranked in the top three most used
third-party packages in the Django Developers Survey in recent years.
This tutorial will show how to add :pypi:`Django Debug Toolbar
<django-debug-toolbar>`, a commonly used third-party package. The Django Debug
Toolbar has ranked in the top three most used third-party packages in the
Django Developers Survey in recent years.
.. admonition:: Where to get help:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 997 B

View File

@@ -41,7 +41,8 @@ If you're not using the default project template, here are the requirements:
<TEMPLATES-OPTIONS>`.
#. If you've customized the :setting:`MIDDLEWARE` setting,
:class:`django.contrib.auth.middleware.AuthenticationMiddleware` and
:class:`django.contrib.sessions.middleware.SessionMiddleware`,
:class:`django.contrib.auth.middleware.AuthenticationMiddleware`, and
:class:`django.contrib.messages.middleware.MessageMiddleware` must be
included.

View File

@@ -197,13 +197,23 @@ Methods
been called for this user.
.. method:: get_user_permissions(obj=None)
.. method:: aget_user_permissions(obj=None)
*Asynchronous version*: ``aget_user_permissions()``
Returns a set of permission strings that the user has directly.
If ``obj`` is passed in, only returns the user permissions for this
specific object.
.. versionchanged:: 5.2
``aget_user_permissions()`` method was added.
.. method:: get_group_permissions(obj=None)
.. method:: aget_group_permissions(obj=None)
*Asynchronous version*: ``aget_group_permissions()``
Returns a set of permission strings that the user has, through their
groups.
@@ -211,7 +221,14 @@ Methods
If ``obj`` is passed in, only returns the group permissions for
this specific object.
.. versionchanged:: 5.2
``aget_group_permissions()`` method was added.
.. method:: get_all_permissions(obj=None)
.. method:: aget_all_permissions(obj=None)
*Asynchronous version*: ``aget_all_permissions()``
Returns a set of permission strings that the user has, both through
group and user permissions.
@@ -219,7 +236,14 @@ Methods
If ``obj`` is passed in, only returns the permissions for this
specific object.
.. versionchanged:: 5.2
``aget_all_permissions()`` method was added.
.. method:: has_perm(perm, obj=None)
.. method:: ahas_perm(perm, obj=None)
*Asynchronous version*: ``ahas_perm()``
Returns ``True`` if the user has the specified permission, where perm
is in the format ``"<app label>.<permission codename>"``. (see
@@ -230,7 +254,14 @@ Methods
If ``obj`` is passed in, this method won't check for a permission for
the model, but for this specific object.
.. versionchanged:: 5.2
``ahas_perm()`` method was added.
.. method:: has_perms(perm_list, obj=None)
.. method:: ahas_perms(perm_list, obj=None)
*Asynchronous version*: ``ahas_perms()``
Returns ``True`` if the user has each of the specified permissions,
where each perm is in the format
@@ -241,13 +272,24 @@ Methods
If ``obj`` is passed in, this method won't check for permissions for
the model, but for the specific object.
.. versionchanged:: 5.2
``ahas_perms()`` method was added.
.. method:: has_module_perms(package_name)
.. method:: ahas_module_perms(package_name)
*Asynchronous version*: ``ahas_module_perms()``
Returns ``True`` if the user has any permissions in the given package
(the Django app label). If the user is inactive, this method will
always return ``False``. For an active superuser, this method will
always return ``True``.
.. versionchanged:: 5.2
``ahas_module_perms()`` method was added.
.. method:: email_user(subject, message, from_email=None, **kwargs)
Sends an email to the user. If ``from_email`` is ``None``, Django uses
@@ -264,6 +306,9 @@ Manager methods
by :class:`~django.contrib.auth.models.BaseUserManager`):
.. method:: create_user(username, email=None, password=None, **extra_fields)
.. method:: acreate_user(username, email=None, password=None, **extra_fields)
*Asynchronous version*: ``acreate_user()``
Creates, saves and returns a :class:`~django.contrib.auth.models.User`.
@@ -285,11 +330,22 @@ Manager methods
See :ref:`Creating users <topics-auth-creating-users>` for example usage.
.. versionchanged:: 5.2
``acreate_user()`` method was added.
.. method:: create_superuser(username, email=None, password=None, **extra_fields)
.. method:: acreate_superuser(username, email=None, password=None, **extra_fields)
*Asynchronous version*: ``acreate_superuser()``
Same as :meth:`create_user`, but sets :attr:`~models.User.is_staff` and
:attr:`~models.User.is_superuser` to ``True``.
.. versionchanged:: 5.2
``acreate_superuser()`` method was added.
.. method:: with_perm(perm, is_active=True, include_superusers=True, backend=None, obj=None)
Returns users that have the given permission ``perm`` either in the
@@ -499,23 +555,51 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
methods. By default, it will reject any user and provide no permissions.
.. method:: get_user_permissions(user_obj, obj=None)
.. method:: aget_user_permissions(user_obj, obj=None)
*Asynchronous version*: ``aget_user_permissions()``
Returns an empty set.
.. versionchanged:: 5.2
``aget_user_permissions()`` function was added.
.. method:: get_group_permissions(user_obj, obj=None)
.. method:: aget_group_permissions(user_obj, obj=None)
*Asynchronous version*: ``aget_group_permissions()``
Returns an empty set.
.. versionchanged:: 5.2
``aget_group_permissions()`` function was added.
.. method:: get_all_permissions(user_obj, obj=None)
.. method:: aget_all_permissions(user_obj, obj=None)
*Asynchronous version*: ``aget_all_permissions()``
Uses :meth:`get_user_permissions` and :meth:`get_group_permissions` to
get the set of permission strings the ``user_obj`` has.
.. versionchanged:: 5.2
``aget_all_permissions()`` function was added.
.. method:: has_perm(user_obj, perm, obj=None)
.. method:: ahas_perm(user_obj, perm, obj=None)
*Asynchronous version*: ``ahas_perm()``
Uses :meth:`get_all_permissions` to check if ``user_obj`` has the
permission string ``perm``.
.. versionchanged:: 5.2
``ahas_perm()`` function was added.
.. class:: ModelBackend
This is the default authentication backend used by Django. It
@@ -539,6 +623,9 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
unlike others methods it returns an empty queryset if ``obj is not None``.
.. method:: authenticate(request, username=None, password=None, **kwargs)
.. method:: aauthenticate(request, username=None, password=None, **kwargs)
*Asynchronous version*: ``aauthenticate()``
Tries to authenticate ``username`` with ``password`` by calling
:meth:`User.check_password
@@ -552,38 +639,77 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
if it wasn't provided to :func:`~django.contrib.auth.authenticate`
(which passes it on to the backend).
.. versionchanged:: 5.2
``aauthenticate()`` function was added.
.. method:: get_user_permissions(user_obj, obj=None)
.. method:: aget_user_permissions(user_obj, obj=None)
*Asynchronous version*: ``aget_user_permissions()``
Returns the set of permission strings the ``user_obj`` has from their
own user permissions. Returns an empty set if
:attr:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
.. versionchanged:: 5.2
``aget_user_permissions()`` function was added.
.. method:: get_group_permissions(user_obj, obj=None)
.. method:: aget_group_permissions(user_obj, obj=None)
*Asynchronous version*: ``aget_group_permissions()``
Returns the set of permission strings the ``user_obj`` has from the
permissions of the groups they belong. Returns an empty set if
:attr:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
.. versionchanged:: 5.2
``aget_group_permissions()`` function was added.
.. method:: get_all_permissions(user_obj, obj=None)
.. method:: aget_all_permissions(user_obj, obj=None)
*Asynchronous version*: ``aget_all_permissions()``
Returns the set of permission strings the ``user_obj`` has, including both
user permissions and group permissions. Returns an empty set if
:attr:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
.. versionchanged:: 5.2
``aget_all_permissions()`` function was added.
.. method:: has_perm(user_obj, perm, obj=None)
.. method:: ahas_perm(user_obj, perm, obj=None)
*Asynchronous version*: ``ahas_perm()``
Uses :meth:`get_all_permissions` to check if ``user_obj`` has the
permission string ``perm``. Returns ``False`` if the user is not
:attr:`~django.contrib.auth.models.CustomUser.is_active`.
.. versionchanged:: 5.2
``ahas_perm()`` function was added.
.. method:: has_module_perms(user_obj, app_label)
.. method:: ahas_module_perms(user_obj, app_label)
*Asynchronous version*: ``ahas_module_perms()``
Returns whether the ``user_obj`` has any permissions on the app
``app_label``.
.. versionchanged:: 5.2
``ahas_module_perms()`` function was added.
.. method:: user_can_authenticate()
Returns whether the user is allowed to authenticate. To match the
@@ -637,6 +763,9 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
created if not already in the database Defaults to ``True``.
.. method:: authenticate(request, remote_user)
.. method:: aauthenticate(request, remote_user)
*Asynchronous version*: ``aauthenticate()``
The username passed as ``remote_user`` is considered trusted. This
method returns the user object with the given username, creating a new
@@ -651,6 +780,10 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
if it wasn't provided to :func:`~django.contrib.auth.authenticate`
(which passes it on to the backend).
.. versionchanged:: 5.2
``aauthenticate()`` function was added.
.. method:: clean_username(username)
Performs any cleaning on the ``username`` (e.g. stripping LDAP DN
@@ -658,12 +791,17 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
the cleaned username.
.. method:: configure_user(request, user, created=True)
.. method:: aconfigure_user(request, user, created=True)
*Asynchronous version*: ``aconfigure_user()``
Configures the user on each authentication attempt. This method is
called immediately after fetching or creating the user being
authenticated, and can be used to perform custom setup actions, such as
setting the user's groups based on attributes in an LDAP directory.
Returns the user object.
Returns the user object. When fetching or creating an user is called
from a synchronous context, ``configure_user`` is called,
``aconfigure_user`` is called from async contexts.
The setup can be performed either once when the user is created
(``created`` is ``True``) or on existing users (``created`` is
@@ -674,6 +812,10 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
if it wasn't provided to :func:`~django.contrib.auth.authenticate`
(which passes it on to the backend).
.. versionchanged:: 5.2
``aconfigure_user()`` function was added.
.. method:: user_can_authenticate()
Returns whether the user is allowed to authenticate. This method

View File

@@ -5,8 +5,8 @@ Geolocation with GeoIP2
.. module:: django.contrib.gis.geoip2
:synopsis: Python interface for MaxMind's GeoIP2 databases.
The :class:`GeoIP2` object is a wrapper for the `MaxMind geoip2 Python
library`__. [#]_
The :class:`GeoIP2` object is a wrapper for the :pypi:`MaxMind geoip2 Python
library <geoip2>`. [#]_
In order to perform IP-based geolocation, the :class:`GeoIP2` object requires
the :pypi:`geoip2` Python package and the GeoIP ``Country`` and/or ``City``
@@ -18,7 +18,6 @@ the :setting:`GEOIP_PATH` setting.
Additionally, it is recommended to install the `libmaxminddb C library`__, so
that ``geoip2`` can leverage the C library's faster speed.
__ https://geoip2.readthedocs.io/
__ https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
__ https://db-ip.com/db/lite.php
__ https://github.com/maxmind/libmaxminddb/
@@ -196,8 +195,9 @@ Exceptions
.. exception:: GeoIP2Exception
The exception raised when an error occurs in a call to the underlying
``geoip2`` library.
The exception raised when an error occurs in the :class:`GeoIP2` wrapper.
Exceptions from the underlying ``geoip2`` library are passed through
unchanged.
.. rubric:: Footnotes
.. [#] GeoIP(R) is a registered trademark of MaxMind, Inc.

View File

@@ -5,16 +5,16 @@ Installing Geospatial libraries
GeoDjango uses and/or provides interfaces for the following open source
geospatial libraries:
======================== ==================================== ================================ ===========================================
======================== ==================================== ================================ ======================================
Program Description Required Supported Versions
======================== ==================================== ================================ ===========================================
======================== ==================================== ================================ ======================================
:doc:`GEOS <../geos>` Geometry Engine Open Source Yes 3.12, 3.11, 3.10, 3.9, 3.8
`PROJ`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 9.x, 8.x, 7.x, 6.x
:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 3.8, 3.7, 3.6, 3.5, 3.4, 3.3, 3.2, 3.1, 3.0
:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 3.8, 3.7, 3.6, 3.5, 3.4, 3.3, 3.2, 3.1
:doc:`GeoIP <../geoip2>` IP-based geolocation library No 2
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.4, 3.3, 3.2, 3.1
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 5.1, 5.0, 4.3
======================== ==================================== ================================ ===========================================
======================== ==================================== ================================ ======================================
Note that older or more recent versions of these libraries *may* also work
totally fine with GeoDjango. Your mileage may vary.
@@ -26,7 +26,6 @@ totally fine with GeoDjango. Your mileage may vary.
GEOS 3.10.0 2021-10-20
GEOS 3.11.0 2022-07-01
GEOS 3.12.0 2023-06-27
GDAL 3.0.0 2019-05
GDAL 3.1.0 2020-05-07
GDAL 3.2.0 2020-11-02
GDAL 3.3.0 2021-05-03

View File

@@ -479,8 +479,6 @@ MySQL has a couple drivers that implement the Python Database API described in
.. _MySQL Connector/Python: https://dev.mysql.com/downloads/connector/python/
These drivers are thread-safe and provide connection pooling.
In addition to a DB API driver, Django needs an adapter to access the database
drivers from its ORM. Django provides an adapter for mysqlclient while MySQL
Connector/Python includes `its own`_.

View File

@@ -870,11 +870,11 @@ are reserved for the superuser (root).
This server uses the WSGI application object specified by the
:setting:`WSGI_APPLICATION` setting.
DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through
security audits or performance tests. (And that's how it's gonna stay. We're in
the business of making web frameworks, not web servers, so improving this
server to be able to handle a production environment is outside the scope of
Django.)
.. warning:: DO NOT USE THIS SERVER IN A PRODUCTION SETTING.
This lightweight development server has not gone through security audits or
performance tests, hence is unsuitable for production. Making this server
able to handle a production environment is outside the scope of Django.
The development server automatically reloads Python code for each request, as
needed. You don't need to restart the server for code changes to take effect.
@@ -947,6 +947,20 @@ multithreaded by default.
Uses IPv6 for the development server. This changes the default IP address from
``127.0.0.1`` to ``::1``.
.. envvar:: HIDE_PRODUCTION_WARNING
.. versionadded:: 5.2
By default, a warning is printed to the console that ``runserver`` is not
suitable for production:
.. code-block:: text
WARNING: This is a development server. Do not use it in a production setting. Use a production WSGI or ASGI server instead.
For more information on production servers see: https://docs.djangoproject.com/en/|version|/howto/deployment/
Set this environment variable to ``"true"`` to hide this warning.
Examples of using different ports and addresses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1078,7 +1092,7 @@ Python interpreter, use ``python`` as the interface name, like so:
.. _IPython: https://ipython.org/
.. _bpython: https://bpython-interpreter.org/
.. django-admin-option:: --nostartup
.. django-admin-option:: --no-startup
Disables reading the startup script for the "plain" Python interpreter. By
default, the script pointed to by the :envvar:`PYTHONSTARTUP` environment

View File

@@ -129,8 +129,7 @@ The ``Storage`` class
.. method:: exists(name)
Returns ``True`` if a file referenced by the given name already exists
in the storage system, or ``False`` if the name is available for a new
file.
in the storage system.
.. method:: get_accessed_time(name)

View File

@@ -801,11 +801,11 @@ For each field, we describe the default widget used if you don't specify
* Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
``invalid_image``
Using an ``ImageField`` requires that `Pillow`_ is installed with support
for the image formats you use. If you encounter a ``corrupt image`` error
when you upload an image, it usually means that Pillow doesn't understand
its format. To fix this, install the appropriate library and reinstall
Pillow.
Using an ``ImageField`` requires that :pypi:`pillow` is installed with
support for the image formats you use. If you encounter a ``corrupt image``
error when you upload an image, it usually means that Pillow doesn't
understand its format. To fix this, install the appropriate library and
reinstall Pillow.
When you use an ``ImageField`` on a form, you must also remember to
:ref:`bind the file data to the form <binding-uploaded-files>`.
@@ -851,7 +851,6 @@ For each field, we describe the default widget used if you don't specify
image's content type if Pillow can determine it, otherwise it will be set
to ``None``.
.. _Pillow: https://pillow.readthedocs.io/en/latest/
.. _Image: https://pillow.readthedocs.io/en/latest/reference/Image.html
``IntegerField``

View File

@@ -570,6 +570,48 @@ These widgets make use of the HTML elements ``input`` and ``textarea``.
* ``template_name``: ``'django/forms/widgets/url.html'``
* Renders as: ``<input type="url" ...>``
``ColorInput``
~~~~~~~~~~~~~~
.. versionadded:: 5.2
.. class:: ColorInput
* ``input_type``: ``'color'``
* ``template_name``:``'django/forms/widgets/color.html'``
* Renders as: ``<input type="color" ...>``
``SearchInput``
~~~~~~~~~~~~~~~
.. versionadded:: 5.2
.. class:: SearchInput
* ``input_type``: ``'search'``
* ``template_name``: ``'django/forms/widgets/search.html'``
* Renders as: ``<input type="search" ...>``
``TelInput``
~~~~~~~~~~~~
.. versionadded:: 5.2
.. class:: TelInput
* ``input_type``: ``'tel'``
* ``template_name``: ``'django/forms/widgets/tel.html'``
* Renders as: ``<input type="tel" ...>``
Browsers perform no client-side validation by default because telephone
number formats vary so much around the world. You can add some by setting
``pattern``, ``minlength``, or ``maxlength`` in the :attr:`Widget.attrs`
argument.
Additionally, you can add server-side validation to your form field with a
validator like :class:`~django.core.validators.RegexValidator` or via
third-party packages, such as :pypi:`django-phonenumber-field`.
``PasswordInput``
~~~~~~~~~~~~~~~~~

View File

@@ -209,6 +209,18 @@ Django development server. This logger generates an ``INFO`` message upon
detecting a modification in a source code file and may produce ``WARNING``
messages during filesystem inspection and event subscription processes.
.. _django-contrib-auth-logger:
``django.contrib.auth``
~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 4.2.16
Log messages related to :doc:`contrib/auth`, particularly ``ERROR`` messages
are generated when a :class:`~django.contrib.auth.forms.PasswordResetForm` is
successfully submitted but the password reset email cannot be delivered due to
a mail sending exception.
.. _django-contrib-gis-logger:
``django.contrib.gis``

View File

@@ -34,6 +34,12 @@ defines. See the :doc:`cache documentation </topics/cache>`.
.. class:: CommonMiddleware
.. attribute:: response_redirect_class
Defaults to :class:`~django.http.HttpResponsePermanentRedirect`. Subclass
``CommonMiddleware`` and override the attribute to customize the redirects
issued by the middleware.
Adds a few conveniences for perfectionists:
* Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS`
@@ -75,12 +81,6 @@ Adds a few conveniences for perfectionists:
* Sets the ``Content-Length`` header for non-streaming responses.
.. attribute:: CommonMiddleware.response_redirect_class
Defaults to :class:`~django.http.HttpResponsePermanentRedirect`. Subclass
``CommonMiddleware`` and override the attribute to customize the redirects
issued by the middleware.
.. class:: BrokenLinkEmailsMiddleware
* Sends broken link notification emails to :setting:`MANAGERS` (see
@@ -164,16 +164,16 @@ Locale middleware
.. class:: LocaleMiddleware
.. attribute:: LocaleMiddleware.response_redirect_class
Defaults to :class:`~django.http.HttpResponseRedirect`. Subclass
``LocaleMiddleware`` and override the attribute to customize the
redirects issued by the middleware.
Enables language selection based on data from the request. It customizes
content for each user. See the :doc:`internationalization documentation
</topics/i18n/translation>`.
.. attribute:: LocaleMiddleware.response_redirect_class
Defaults to :class:`~django.http.HttpResponseRedirect`. Subclass
``LocaleMiddleware`` and override the attribute to customize the redirects
issued by the middleware.
Message middleware
------------------
@@ -500,56 +500,81 @@ every incoming ``HttpRequest`` object. See :ref:`Authentication in web requests
.. class:: LoginRequiredMiddleware
Subclass the middleware and override the following attributes and methods
to customize behavior for unauthenticated requests.
.. attribute:: redirect_field_name
Defaults to ``"next"``.
.. method:: get_login_url()
Returns the URL that unauthenticated requests will be redirected to. This
result is either the ``login_url`` set on the
:func:`~django.contrib.auth.decorators.login_required` decorator (if not
``None``), or :setting:`settings.LOGIN_URL <LOGIN_URL>`.
.. method:: get_redirect_field_name()
Returns the name of the query parameter that contains the URL the user
should be redirected to after a successful login. This result is either
the ``redirect_field_name`` set on the
:func:`~.django.contrib.auth.decorators.login_required` decorator (if not
``None``), or :attr:`redirect_field_name`. If ``None`` is returned, a query
parameter won't be added.
.. versionadded:: 5.1
Redirects all unauthenticated requests to a login page. For admin views, this
redirects to the admin login. For all other views, this will redirect to
:setting:`settings.LOGIN_URL <LOGIN_URL>`. This can be customized by using the
:func:`~.django.contrib.auth.decorators.login_required` decorator and setting
``login_url`` or ``redirect_field_name`` for the view. For example::
Redirects all unauthenticated requests to a login page, except for views
excluded with :func:`~.django.contrib.auth.decorators.login_not_required`. The
login page defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>`, but can be
customized.
Enable this middleware by adding it to the :setting:`MIDDLEWARE` setting
**after** :class:`~django.contrib.auth.middleware.AuthenticationMiddleware`::
MIDDLEWARE = [
"...",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.auth.middleware.LoginRequiredMiddleware",
"...",
]
Make a view public, allowing unauthenticated requests, with
:func:`~.django.contrib.auth.decorators.login_not_required`. For example::
from django.contrib.auth.decorators import login_not_required
@login_not_required
def contact_us(request): ...
Customize the login URL or field name for authenticated views with the
:func:`~.django.contrib.auth.decorators.login_required` decorator to set
``login_url`` or ``redirect_field_name`` respectively. For example::
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import View
@login_required(login_url="/books/login/", redirect_field_name="redirect_to")
def book_dashboard(request): ...
@method_decorator(
login_required(login_url="/login/", redirect_field_name="redirect_to"),
login_required(login_url="/books/login/", redirect_field_name="redirect_to"),
name="dispatch",
)
class MyView(View):
class BookMetrics(View):
pass
@login_required(login_url="/login/", redirect_field_name="redirect_to")
def my_view(request): ...
Views using the :func:`~django.contrib.auth.decorators.login_not_required`
decorator are exempt from this requirement.
.. admonition:: Ensure that your login view does not require a login.
To prevent infinite redirects, ensure you have
:ref:`enabled unauthenticated requests
<disable-login-required-middleware-for-views>` to your login view.
**Methods and Attributes**
.. attribute:: redirect_field_name
Defaults to ``"next"``.
.. method:: get_login_url()
Returns the URL that unauthenticated requests will be redirected to. If
defined, this returns the ``login_url`` set on the
:func:`~.django.contrib.auth.decorators.login_required` decorator. Defaults
to :setting:`settings.LOGIN_URL <LOGIN_URL>`.
.. method:: get_redirect_field_name()
Returns the name of the query parameter that contains the URL the user
should be redirected to after a successful login. If defined, this returns
the ``redirect_field_name`` set on the
:func:`~.django.contrib.auth.decorators.login_required` decorator. Defaults
to :attr:`redirect_field_name`. If ``None`` is returned, a query parameter
won't be added.
.. class:: RemoteUserMiddleware
Middleware for utilizing web server provided authentication. See

View File

@@ -975,9 +975,9 @@ frame includes all rows from the partition to the last row in the set.
The accepted values for the ``start`` and ``end`` arguments are ``None``, an
integer, or zero. A negative integer for ``start`` results in ``N PRECEDING``,
while ``None`` yields ``UNBOUNDED PRECEDING``. In ``ROWS`` mode, a positive
integer can be used for ```start`` resulting in ``N FOLLOWING``. Positive
integer can be used for ``start`` resulting in ``N FOLLOWING``. Positive
integers are accepted for ``end`` and results in ``N FOLLOWING``. In ``ROWS``
mode, a negative integer can be used for ```end`` resulting in ``N PRECEDING``.
mode, a negative integer can be used for ``end`` resulting in ``N PRECEDING``.
For both ``start`` and ``end``, zero will return ``CURRENT ROW``.
There's a difference in what ``CURRENT ROW`` includes. When specified in
@@ -1095,6 +1095,16 @@ calling the appropriate methods on the wrapped expression.
:py:data:`NotImplemented` which forces the expression to be computed on
the database.
.. attribute:: set_returning
.. versionadded:: 5.2
Tells Django that this expression contains a set-returning function,
enforcing subquery evaluation. It's used, for example, to allow some
Postgres set-returning functions (e.g. ``JSONB_PATH_QUERY``,
``UNNEST``, etc.) to skip optimization and be properly evaluated when
annotations spawn rows themselves. Defaults to ``False``.
.. method:: resolve_expression(query=None, allow_joins=True, reuse=None, summarize=False, for_save=False)
Provides the chance to do any preprocessing or validation of

View File

@@ -12,8 +12,8 @@ This document contains all the API references of :class:`Field` including the
.. seealso::
If the built-in fields don't do the trick, you can try `django-localflavor
<https://github.com/django/django-localflavor>`_ (`documentation
If the built-in fields don't do the trick, you can try
:pypi:`django-localflavor` (`documentation
<https://django-localflavor.readthedocs.io/>`_), which contains assorted
pieces of code that are useful for particular countries and cultures.
@@ -43,13 +43,15 @@ If ``True``, Django will store empty values as ``NULL`` in the database. Default
is ``False``.
Avoid using :attr:`~Field.null` on string-based fields such as
:class:`CharField` and :class:`TextField`. If a string-based field has
``null=True``, that means it has two possible values for "no data": ``NULL``,
and the empty string. In most cases, it's redundant to have two possible values
for "no data;" the Django convention is to use the empty string, not
``NULL``. One exception is when a :class:`CharField` has both ``unique=True``
and ``blank=True`` set. In this situation, ``null=True`` is required to avoid
unique constraint violations when saving multiple objects with blank values.
:class:`CharField` and :class:`TextField`. The Django convention is to use an
empty string, not ``NULL``, as the "no data" state for string-based fields. If a
string-based field has ``null=False``, empty strings can still be saved for "no
data". If a string-based field has ``null=True``, that means it has two possible
values for "no data": ``NULL``, and the empty string. In most cases, it's
redundant to have two possible values for "no data". One exception is when a
:class:`CharField` has both ``unique=True`` and ``blank=True`` set. In this
situation, ``null=True`` is required to avoid unique constraint violations when
saving multiple objects with blank values.
For both string-based and non-string-based fields, you will also need to
set ``blank=True`` if you wish to permit empty values in forms, as the
@@ -718,8 +720,8 @@ The default form widget for this field is a :class:`~django.forms.TextInput`.
The maximum length (in characters) of the field. The ``max_length``
is enforced at the database level and in Django's validation using
:class:`~django.core.validators.MaxLengthValidator`. It's required for all
database backends included with Django except PostgreSQL, which supports
unlimited ``VARCHAR`` columns.
database backends included with Django except PostgreSQL and SQLite, which
supports unlimited ``VARCHAR`` columns.
.. note::
@@ -728,6 +730,10 @@ The default form widget for this field is a :class:`~django.forms.TextInput`.
``max_length`` for some backends. Refer to the :doc:`database backend
notes </ref/databases>` for details.
.. versionchanged:: 5.2
Support for unlimited ``VARCHAR`` columns was added on SQLite.
.. attribute:: CharField.db_collation
Optional. The database collation name of the field.
@@ -1357,9 +1363,7 @@ following optional arguments:
Name of a model field which is auto-populated with the width of the image
each time an image object is set.
Requires the `Pillow`_ library.
.. _Pillow: https://pillow.readthedocs.io/en/latest/
Requires the :pypi:`pillow` library.
:class:`ImageField` instances are created in your database as ``varchar``
columns with a default max length of 100 characters. As with other fields, you
@@ -2441,6 +2445,9 @@ Field API reference
Returns the default :class:`django.forms.Field` of this field for
:class:`~django.forms.ModelForm`.
If :meth:`~Field.formfield` is overridden to return ``None``, this field
is excluded from the :class:`~django.forms.ModelForm`.
By default, if both ``form_class`` and ``choices_form_class`` are
``None``, it uses :class:`~django.forms.CharField`. If the field has
:attr:`~django.db.models.Field.choices` and ``choices_form_class``

View File

@@ -973,3 +973,14 @@ Other attributes
since they are yet to be saved. Instances fetched from a ``QuerySet``
will have ``adding=False`` and ``db`` set to the alias of the associated
database.
``_is_pk_set()``
----------------
.. method:: Model._is_pk_set()
.. versionadded:: 5.2
The ``_is_pk_set()`` method returns whether the model instance's ``pk`` is set.
It abstracts the model's primary key definition, ensuring consistent behavior
regardless of the specific ``pk`` configuration.

View File

@@ -1599,9 +1599,7 @@ of the arguments is required, but you should use at least one of them.
FROM blog_blog;
Note that the parentheses required by most database engines around
subqueries are not required in Django's ``select`` clauses. Also note
that some database backends, such as some MySQL versions, don't support
subqueries.
subqueries are not required in Django's ``select`` clauses.
In some rare cases, you might wish to pass parameters to the SQL
fragments in ``extra(select=...)``. For this purpose, use the

View File

@@ -425,10 +425,48 @@ Methods
Returns ``True`` if the request is secure; that is, if it was made with
HTTPS.
.. method:: HttpRequest.get_preferred_type(media_types)
.. versionadded:: 5.2
Returns the preferred mime type from ``media_types``, based on the
``Accept`` header, or ``None`` if the client does not accept any of the
provided types.
Assuming the client sends an ``Accept`` header of
``text/html,application/json;q=0.8``:
.. code-block:: pycon
>>> request.get_preferred_type(["text/html", "application/json"])
"text/html"
>>> request.get_preferred_type(["application/json", "text/plain"])
"application/json"
>>> request.get_preferred_type(["application/xml", "text/plain"])
None
Most browsers send ``Accept: */*`` by default, meaning they don't have a
preference, in which case the first item in ``media_types`` would be
returned.
Setting an explicit ``Accept`` header in API requests can be useful for
returning a different content type for those consumers only. See
:ref:`content-negotiation-example` for an example of returning
different content based on the ``Accept`` header.
.. note::
If a response varies depending on the content of the ``Accept`` header
and you are using some form of caching like Django's
:mod:`cache middleware <django.middleware.cache>`, you should decorate
the view with :func:`vary_on_headers('Accept')
<django.views.decorators.vary.vary_on_headers>` so that the responses
are properly cached.
.. method:: HttpRequest.accepts(mime_type)
Returns ``True`` if the request ``Accept`` header matches the ``mime_type``
argument:
Returns ``True`` if the request's ``Accept`` header matches the
``mime_type`` argument:
.. code-block:: pycon
@@ -436,17 +474,10 @@ Methods
True
Most browsers send ``Accept: */*`` by default, so this would return
``True`` for all content types. Setting an explicit ``Accept`` header in
API requests can be useful for returning a different content type for those
consumers only. See :ref:`content-negotiation-example` of using
``accepts()`` to return different content to API consumers.
``True`` for all content types.
If a response varies depending on the content of the ``Accept`` header and
you are using some form of caching like Django's :mod:`cache middleware
<django.middleware.cache>`, you should decorate the view with
:func:`vary_on_headers('Accept')
<django.views.decorators.vary.vary_on_headers>` so that the responses are
properly cached.
See :ref:`content-negotiation-example` for an example of using
``accepts()`` to return different content based on the ``Accept`` header.
.. method:: HttpRequest.read(size=None)
.. method:: HttpRequest.readline()

View File

@@ -3636,6 +3636,7 @@ Email
* :setting:`EMAIL_SUBJECT_PREFIX`
* :setting:`EMAIL_TIMEOUT`
* :setting:`EMAIL_USE_LOCALTIME`
* :setting:`EMAIL_USE_SSL`
* :setting:`EMAIL_USE_TLS`
* :setting:`MANAGERS`
* :setting:`SERVER_EMAIL`

View File

@@ -660,7 +660,6 @@ settings file, the default template engine contains the following context
processors::
[
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",

View File

@@ -2883,8 +2883,8 @@ If ``value`` is ``"https://www.example.org/"``, the output will be
Converts URLs and email addresses in text into clickable links.
This template tag works on links prefixed with ``http://``, ``https://``, or
``www.``. For example, ``https://goo.gl/aia1t`` will get converted but
``goo.gl/aia1t`` won't.
``www.``. For example, ``https://djangocon.eu`` will get converted but
``djangocon.eu`` won't.
It also supports domain-only links ending in one of the original top level
domains (``.com``, ``.edu``, ``.gov``, ``.int``, ``.mil``, ``.net``, and
@@ -2922,6 +2922,17 @@ Django's built-in :tfilter:`escape` filter. The default value for
email addresses that contain single quotes (``'``), things won't work as
expected. Apply this filter only to plain text.
.. warning::
Using ``urlize`` or ``urlizetrunc`` can incur a performance penalty, which
can become severe when applied to user controlled values such as content
stored in a :class:`~django.db.models.TextField`. You can use
:tfilter:`truncatechars` to add a limit to such inputs:
.. code-block:: html+django
{{ value|truncatechars:500|urlize }}
.. templatefilter:: urlizetrunc
``urlizetrunc``

View File

@@ -25,6 +25,9 @@ Returns an element for inclusion in ``urlpatterns``. For example::
...,
]
``route``
---------
The ``route`` argument should be a string or
:func:`~django.utils.translation.gettext_lazy()` (see
:ref:`translating-urlpatterns`) that contains a URL pattern. The string
@@ -33,16 +36,43 @@ URL and send it as a keyword argument to the view. The angle brackets may
include a converter specification (like the ``int`` part of ``<int:section>``)
which limits the characters matched and may also change the type of the
variable passed to the view. For example, ``<int:section>`` matches a string
of decimal digits and converts the value to an ``int``. See
of decimal digits and converts the value to an ``int``.
When processing a request, Django starts at the first pattern in
``urlpatterns`` and makes its way down the list, comparing the requested URL
against each pattern until it finds one that matches. See
:ref:`how-django-processes-a-request` for more details.
Patterns don't match GET and POST parameters, or the domain name. For example,
in a request to ``https://www.example.com/myapp/``, the URLconf will look for
``myapp/``. In a request to ``https://www.example.com/myapp/?page=3``, the
URLconf will also look for ``myapp/``.
``view``
--------
The ``view`` argument is a view function or the result of
:meth:`~django.views.generic.base.View.as_view` for class-based views. It can
also be an :func:`django.urls.include`.
also be a :func:`django.urls.include`.
When Django finds a matching pattern, it calls the specified view function with
an :class:`~django.http.HttpRequest` object as the first argument and any
"captured" values from the route as keyword arguments.
``kwargs``
----------
The ``kwargs`` argument allows you to pass additional arguments to the view
function or method. See :ref:`views-extra-options` for an example.
``name``
--------
Naming your URL lets you refer to it unambiguously from elsewhere in Django,
especially from within templates. This powerful feature allows you to make
global changes to the URL patterns of your project while only touching a single
file.
See :ref:`Naming URL patterns <naming-url-patterns>` for why the ``name``
argument is useful.

View File

@@ -699,10 +699,29 @@ escaping HTML.
joined using ``sep``. ``sep`` is also passed through
:func:`conditional_escape`.
``args_generator`` should be an iterator that returns the sequence of
``args`` that will be passed to :func:`format_html`. For example::
``args_generator`` should be an iterator that yields arguments to pass to
:func:`format_html`, either sequences of positional arguments or mappings of
keyword arguments.
format_html_join("\n", "<li>{} {}</li>", ((u.first_name, u.last_name) for u in users))
For example, tuples can be used for positional arguments::
format_html_join(
"\n",
"<li>{} {}</li>",
((u.first_name, u.last_name) for u in users),
)
Or dictionaries can be used for keyword arguments::
format_html_join(
"\n",
'<li data-id="{id}">{id} {title}</li>',
({"id": b.id, "title": b.title} for b in books),
)
.. versionchanged:: 5.2
Support for mappings in ``args_generator`` was added.
.. function:: json_script(value, element_id=None, encoder=None)
@@ -1148,7 +1167,7 @@ For a complete discussion on the usage of the following see the
``'es-ar'`` isn't.
``lang_code`` has a maximum accepted length of 500 characters. A
:exc:`ValueError` is raised if ``lang_code`` exceeds this limit and
:exc:`LookupError` is raised if ``lang_code`` exceeds this limit and
``strict`` is ``True``, or if there is no generic variant and ``strict``
is ``False``.
@@ -1160,10 +1179,10 @@ For a complete discussion on the usage of the following see the
Raises :exc:`LookupError` if nothing is found.
.. versionchanged:: 4.2.14
.. versionchanged:: 4.2.15
In older versions, ``lang_code`` values over 500 characters were
processed without raising a :exc:`ValueError`.
processed without raising a :exc:`LookupError`.
.. function:: to_locale(language)

45
docs/releases/4.2.15.txt Normal file
View File

@@ -0,0 +1,45 @@
===========================
Django 4.2.15 release notes
===========================
*August 6, 2024*
Django 4.2.15 fixes three security issues with severity "moderate", one
security issue with severity "high", and a regression in 4.2.14.
CVE-2024-41989: Memory exhaustion in ``django.utils.numberformat.floatformat()``
================================================================================
If :tfilter:`floatformat` received a string representation of a number in
scientific notation with a large exponent, it could lead to significant memory
consumption.
To avoid this, decimals with more than 200 digits are now returned as is.
CVE-2024-41990: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.
CVE-2024-41991: Potential denial-of-service vulnerability in ``django.utils.html.urlize()`` and ``AdminURLFieldWidget``
=======================================================================================================================
:tfilter:`urlize`, :tfilter:`urlizetrunc`, and ``AdminURLFieldWidget`` were
subject to a potential denial-of-service attack via certain inputs with a very
large number of Unicode characters.
CVE-2024-42005: Potential SQL injection in ``QuerySet.values()`` and ``values_list()``
======================================================================================
:meth:`.QuerySet.values` and :meth:`~.QuerySet.values_list` methods on models
with a ``JSONField`` were subject to SQL injection in column aliases, via a
crafted JSON object key as a passed ``*arg``.
Bugfixes
========
* Fixed a regression in Django 4.2.14 that caused a crash in
``LocaleMiddleware`` when processing a language code over 500 characters
(:ticket:`35627`).

26
docs/releases/4.2.16.txt Normal file
View File

@@ -0,0 +1,26 @@
===========================
Django 4.2.16 release notes
===========================
*September 3, 2024*
Django 4.2.16 fixes one security issue with severity "moderate" and one
security issue with severity "low" in 4.2.15.
CVE-2024-45230: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.
CVE-2024-45231: Potential user email enumeration via response status on password reset
======================================================================================
Due to unhandled email sending failures, the
:class:`~django.contrib.auth.forms.PasswordResetForm` class allowed remote
attackers to enumerate user emails by issuing password reset requests and
observing the outcomes.
To mitigate this risk, exceptions occurring during password reset email sending
are now handled and logged using the :ref:`django-contrib-auth-logger` logger.

View File

@@ -2,9 +2,40 @@
Django 5.0.8 release notes
==========================
*Expected August 6, 2024*
*August 6, 2024*
Django 5.0.8 fixes several bugs in 5.0.7.
Django 5.0.8 fixes three security issues with severity "moderate", one security
issue with severity "high", and several bugs in 5.0.7.
CVE-2024-41989: Memory exhaustion in ``django.utils.numberformat.floatformat()``
================================================================================
If :tfilter:`floatformat` received a string representation of a number in
scientific notation with a large exponent, it could lead to significant memory
consumption.
To avoid this, decimals with more than 200 digits are now returned as is.
CVE-2024-41990: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.
CVE-2024-41991: Potential denial-of-service vulnerability in ``django.utils.html.urlize()`` and ``AdminURLFieldWidget``
=======================================================================================================================
:tfilter:`urlize`, :tfilter:`urlizetrunc`, and ``AdminURLFieldWidget`` were
subject to a potential denial-of-service attack via certain inputs with a very
large number of Unicode characters.
CVE-2024-42005: Potential SQL injection in ``QuerySet.values()`` and ``values_list()``
======================================================================================
:meth:`.QuerySet.values` and :meth:`~.QuerySet.values_list` methods on models
with a ``JSONField`` were subject to SQL injection in column aliases, via a
crafted JSON object key as a passed ``*arg``.
Bugfixes
========
@@ -15,3 +46,22 @@ Bugfixes
* Fixed a regression in Django 5.0 where ``ModelAdmin.action_checkbox`` could
break the admin changelist HTML page when rendering a model instance with a
``__html__`` method (:ticket:`35606`).
* Fixed a crash when creating a model with a ``Field.db_default`` and a
``Meta.constraints`` constraint composed of ``__endswith``, ``__startswith``,
or ``__contains`` lookups (:ticket:`35625`).
* Fixed a regression in Django 5.0.7 that caused a crash in
``LocaleMiddleware`` when processing a language code over 500 characters
(:ticket:`35627`).
* Fixed a bug in Django 5.0 that caused a system check crash when
``ModelAdmin.date_hierarchy`` was a ``GeneratedField`` with an
``output_field`` of ``DateField`` or ``DateTimeField`` (:ticket:`35628`).
* Fixed a bug in Django 5.0 which caused constraint validation to either crash
or incorrectly raise validation errors for constraints referring to fields
using ``Field.db_default`` (:ticket:`35638`).
* Fixed a crash in Django 5.0 when saving a model containing a ``FileField``
with a ``db_default`` set (:ticket:`35657`).

26
docs/releases/5.0.9.txt Normal file
View File

@@ -0,0 +1,26 @@
===========================
Django 5.0.9 release notes
===========================
*September 3, 2024*
Django 5.0.9 fixes one security issue with severity "moderate" and one security
issue with severity "low" in 5.0.8.
CVE-2024-45230: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.
CVE-2024-45231: Potential user email enumeration via response status on password reset
======================================================================================
Due to unhandled email sending failures, the
:class:`~django.contrib.auth.forms.PasswordResetForm` class allowed remote
attackers to enumerate user emails by issuing password reset requests and
observing the outcomes.
To mitigate this risk, exceptions occurring during password reset email sending
are now handled and logged using the :ref:`django-contrib-auth-logger` logger.

58
docs/releases/5.1.1.txt Normal file
View File

@@ -0,0 +1,58 @@
==========================
Django 5.1.1 release notes
==========================
*September 3, 2024*
Django 5.1.1 fixes one security issue with severity "moderate", one security
issue with severity "low", and several bugs in 5.1.
CVE-2024-45230: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.
CVE-2024-45231: Potential user email enumeration via response status on password reset
======================================================================================
Due to unhandled email sending failures, the
:class:`~django.contrib.auth.forms.PasswordResetForm` class allowed remote
attackers to enumerate user emails by issuing password reset requests and
observing the outcomes.
To mitigate this risk, exceptions occurring during password reset email sending
are now handled and logged using the :ref:`django-contrib-auth-logger` logger.
Bugfixes
========
* Fixed a regression in Django 5.1 that caused a crash of ``Window()`` when
passing an empty sequence to the ``order_by`` parameter, and a crash of
``Prefetch()`` for a sliced queryset without ordering (:ticket:`35665`).
* Fixed a regression in Django 5.1 where a new ``usable_password`` field was
included in :class:`~django.contrib.auth.forms.BaseUserCreationForm` (and
children). A new :class:`~django.contrib.auth.forms.AdminUserCreationForm`
including this field was added, isolating the feature to the admin where it
was intended (:ticket:`35678`).
* Adjusted the deprecation warning ``stacklevel`` in :meth:`.Model.save` and
:meth:`.Model.asave` to correctly point to the offending call site
(:ticket:`35060`).
* Adjusted the deprecation warning ``stacklevel`` when using ``OS_OPEN_FLAGS``
in :class:`~django.core.files.storage.FileSystemStorage` to correctly point
to the offending call site (:ticket:`35326`).
* Adjusted the deprecation warning ``stacklevel`` in
``FieldCacheMixin.get_cache_name()`` to correctly point to the offending call
site (:ticket:`35405`).
* Restored, following a regression in Django 5.1, the ability to override the
timezone and role setting behavior used within the ``init_connection_state``
method of the PostgreSQL backend (:ticket:`35688`).
* Fixed a bug in Django 5.1 where variable lookup errors were logged when
rendering admin fieldsets (:ticket:`35716`).

22
docs/releases/5.1.2.txt Normal file
View File

@@ -0,0 +1,22 @@
==========================
Django 5.1.2 release notes
==========================
*October 8, 2024*
Django 5.1.2 fixes several bugs in 5.1.1. Also, the latest string translations
from Transifex are incorporated.
Bugfixes
========
* Fixed a regression in Django 5.1 that caused a crash when using the
PostgreSQL lookup :lookup:`trigram_similar` on output fields from ``Concat``
(:ticket:`35732`).
* Fixed a regression in Django 5.1 that caused a crash of ``JSONObject()``
when using server-side binding with PostgreSQL 16+ (:ticket:`35734`).
* Fixed a regression in Django 5.1 that made selected items in multi-select
widgets indistinguishable from non-selected items in the admin dark theme
(:ticket:`35809`).

13
docs/releases/5.1.3.txt Normal file
View File

@@ -0,0 +1,13 @@
==========================
Django 5.1.3 release notes
==========================
*Expected November 5, 2024*
Django 5.1.3 fixes several bugs in 5.1.2 and adds compatibility with Python
3.13.
Bugfixes
========
* ...

View File

@@ -1,8 +1,8 @@
============================================
Django 5.1 release notes - UNDER DEVELOPMENT
============================================
========================
Django 5.1 release notes
========================
*Expected August 2024*
*August 7, 2024*
Welcome to Django 5.1!
@@ -18,8 +18,9 @@ project.
Python compatibility
====================
Django 5.1 supports Python 3.10, 3.11, and 3.12. We **highly recommend** and
only officially support the latest release of each series.
Django 5.1 supports Python 3.10, 3.11, 3.12, and 3.13 (as of 5.1.3). We
**highly recommend** and only officially support the latest release of each
series.
.. _whats-new-5.1:
@@ -91,12 +92,15 @@ redirects all unauthenticated requests to a login page. Views can allow
unauthenticated requests by using the new
:func:`~django.contrib.auth.decorators.login_not_required` decorator.
The :class:`~django.contrib.auth.middleware.LoginRequiredMiddleware` respects
the ``login_url`` and ``redirect_field_name`` values set via the
``LoginRequiredMiddleware`` respects the ``login_url`` and
``redirect_field_name`` values set via the
:func:`~.django.contrib.auth.decorators.login_required` decorator, but does not
support setting ``login_url`` or ``redirect_field_name`` via the
:class:`~django.contrib.auth.mixins.LoginRequiredMixin`.
To enable this, add ``"django.contrib.auth.middleware.LoginRequiredMiddleware"``
to your :setting:`MIDDLEWARE` setting.
Minor features
--------------
@@ -115,11 +119,11 @@ Minor features
* The default ``parallelism`` of the ``ScryptPasswordHasher`` is
increased from 1 to 5, to follow OWASP recommendations.
* :class:`~django.contrib.auth.forms.BaseUserCreationForm` and
:class:`~django.contrib.auth.forms.AdminPasswordChangeForm` now support
disabling password-based authentication by setting an unusable password on
form save. This is now available in the admin when visiting the user creation
and password change pages.
* The new :class:`~django.contrib.auth.forms.AdminUserCreationForm` and
the existing :class:`~django.contrib.auth.forms.AdminPasswordChangeForm` now
support disabling password-based authentication by setting an unusable
password on form save. This is now available in the admin when visiting the
user creation and password change pages.
* :func:`~.django.contrib.auth.decorators.login_required`,
:func:`~.django.contrib.auth.decorators.permission_required`, and
@@ -394,6 +398,9 @@ Miscellaneous
``width_field`` and ``height_field`` will not match the width and height of
the image.
* The minimum supported version of ``asgiref`` is increased from 3.7.0 to
3.8.1.
.. _deprecated-features-5.1:
Features deprecated in 5.1

View File

@@ -52,6 +52,36 @@ 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``
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()`
* Auth backends can now provide async implementations which are used when
calling async auth functions (e.g.
:func:`~.django.contrib.auth.aauthenticate`) to reduce context-switching which
improves performance. See :ref:`adding an async interface
<writing-authentication-backends-async-interface>` for more details.
:mod:`django.contrib.contenttypes`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -128,7 +158,8 @@ Database backends
Decorators
~~~~~~~~~~
* ...
* :func:`~django.utils.decorators.method_decorator` now supports wrapping
asynchronous view methods.
Email
~~~~~
@@ -150,7 +181,8 @@ Email
Error Reporting
~~~~~~~~~~~~~~~
* ...
* The attribute :attr:`.SafeExceptionReporterFilter.hidden_settings` now
treats values as sensitive if their name includes ``AUTH``.
File Storage
~~~~~~~~~~~~
@@ -165,7 +197,15 @@ File Uploads
Forms
~~~~~
* ...
* The new :class:`~django.forms.ColorInput` form widget is for entering a color
in ``rrggbb`` hexadecimal format and renders as ``<input type="color" ...>``.
Some browsers support a visual color picker interface for this input type.
* The new :class:`~django.forms.SearchInput` form widget is for entering search
queries and renders as ``<input type="search" ...>``.
* The new :class:`~django.forms.TelInput` form widget is for entering telephone
numbers and renders as ``<input type="tel" ...>``.
Generic Views
~~~~~~~~~~~~~
@@ -185,7 +225,10 @@ Logging
Management Commands
~~~~~~~~~~~~~~~~~~~
* ...
* A new warning is printed to the console when running :djadmin:`runserver` that
``runserver`` is unsuitable for production. This warning can be hidden by
setting the :envvar:`HIDE_PRODUCTION_WARNING` environment variable to
``"true"``.
Migrations
~~~~~~~~~~
@@ -203,10 +246,22 @@ Models
methods such as
:meth:`QuerySet.union()<django.db.models.query.QuerySet.union>` unpredictable.
* Added support for validation of model constraints which use a
:class:`~django.db.models.GeneratedField`.
* The new :attr:`.Expression.set_returning` attribute specifies that the
expression contains a set-returning function, enforcing subquery evaluation.
This is necessary for many Postgres set-returning functions.
* :attr:`CharField.max_length <django.db.models.CharField.max_length>` is no
longer required to be set on SQLite, which supports unlimited ``VARCHAR``
columns.
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~
* ...
* The new :meth:`.HttpRequest.get_preferred_type` method can be used to query
the preferred media type the client accepts.
Security
~~~~~~~~
@@ -216,7 +271,9 @@ Security
Serialization
~~~~~~~~~~~~~
* ...
* Each serialization format now defines a ``Deserializer`` class, rather than a
function, to improve extensibility when defining a
:ref:`custom serialization format <custom-serialization-formats>`.
Signals
~~~~~~~
@@ -231,7 +288,14 @@ Templates
Tests
~~~~~
* ...
* Stack frames from Django's custom assertions are now hidden. This makes test
failures easier to read and enables :option:`test --pdb` to directly enter
into the failing test method.
* Data loaded from :attr:`~django.test.TransactionTestCase.fixtures` and from
migrations enabled with :ref:`serialized_rollback=True
<test-case-serialized-rollback>` are now available during
``TransactionTestCase.setUpClass()``.
URLs
~~~~
@@ -241,7 +305,14 @@ URLs
Utilities
~~~~~~~~~
* ...
* :class:`~django.utils.safestring.SafeString` now returns
:py:data:`NotImplemented` in ``__add__`` for non-string right-hand side
values. This aligns with the :py:class:`str` addition behavior and allows
``__radd__`` to be used if available.
* :func:`~django.utils.html.format_html_join` now supports taking an iterable
of mappings, passing their contents as keyword arguments to
:func:`~django.utils.html.format_html`.
Validators
~~~~~~~~~~
@@ -259,13 +330,17 @@ Database backend API
This section describes changes that may be needed in third-party database
backends.
* ...
* The new :meth:`Model._is_pk_set() <django.db.models.Model._is_pk_set>` method
allows checking if a Model instance's primary key is defined.
:mod:`django.contrib.gis`
-------------------------
* Support for PostGIS 3.0 is removed.
* Support for GDAL 3.0 is removed.
Dropped support for PostgreSQL 13
---------------------------------
@@ -275,7 +350,16 @@ PostgreSQL 14 and higher.
Miscellaneous
-------------
* ...
* Adding :attr:`.EmailMultiAlternatives.alternatives` is now only supported via
the :meth:`~.EmailMultiAlternatives.attach_alternative` method.
* The minimum supported version of ``gettext`` is increased from 0.15 to 0.19.
* ``HttpRequest.accepted_types`` is now sorted by the client's preference, based
on the request's ``Accept`` header.
* The :func:`~django.template.context_processors.debug` context processor is no
longer included in the default project template.
.. _deprecated-features-5.2:

View File

@@ -32,6 +32,9 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
5.1.3
5.1.2
5.1.1
5.1
5.0 release
@@ -39,6 +42,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
5.0.9
5.0.8
5.0.7
5.0.6
@@ -55,6 +59,8 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
4.2.16
4.2.15
4.2.14
4.2.13
4.2.12

View File

@@ -36,6 +36,68 @@ Issues under Django's security process
All security issues have been handled under versions of Django's security
process. These are listed below.
September 3, 2024 - :cve:`2024-45231`
-------------------------------------
Potential user email enumeration via response status on password reset.
`Full description
<https://www.djangoproject.com/weblog/2024/sep/03/security-releases/>`__
* Django 5.1 :commit:`(patch) <3c733c78d6f8e50296d6e248968b6516c92a53ca>`
* Django 5.0 :commit:`(patch) <96d84047715ea1715b4bd1594e46122b8a77b9e2>`
* Django 4.2 :commit:`(patch) <bf4888d317ba4506d091eeac6e8b4f1fcc731199>`
September 3, 2024 - :cve:`2024-45230`
-------------------------------------
Potential denial-of-service vulnerability in ``django.utils.html.urlize()``.
`Full description
<https://www.djangoproject.com/weblog/2024/sep/03/security-releases/>`__
* Django 5.1 :commit:`(patch) <022ab0a75c76ab2ea31dfcc5f2cf5501e378d397>`
* Django 5.0 :commit:`(patch) <813de2672bd7361e9a453ab62cd6e52f96b6525b>`
* Django 4.2 :commit:`(patch) <d147a8ebbdf28c17cafbbe2884f0bc57e2bf82e2>`
August 6, 2024 - :cve:`2024-42005`
----------------------------------
Potential SQL injection in ``QuerySet.values()`` and ``values_list()``.
`Full description
<https://www.djangoproject.com/weblog/2024/aug/06/security-releases/>`__
* Django 5.0 :commit:`(patch) <32ebcbf2e1fe3e5ba79a6554a167efce81f7422d>`
* Django 4.2 :commit:`(patch) <f4af67b9b41e0f4c117a8741da3abbd1c869ab28>`
August 6, 2024 - :cve:`2024-41991`
----------------------------------
Potential denial-of-service vulnerability in ``django.utils.html.urlize()`` and
``AdminURLFieldWidget``. `Full description
<https://www.djangoproject.com/weblog/2024/aug/06/security-releases/>`__
* Django 5.0 :commit:`(patch) <523da8771bce321023f490f70d71a9e973ddc927>`
* Django 4.2 :commit:`(patch) <efea1ef7e2190e3f77ca0651b5458297bc0f6a9f>`
August 6, 2024 - :cve:`2024-41990`
----------------------------------
Potential denial-of-service vulnerability in ``django.utils.html.urlize()``.
`Full description
<https://www.djangoproject.com/weblog/2024/aug/06/security-releases/>`__
* Django 5.0 :commit:`(patch) <7b7b909579c8311c140c89b8a9431bf537febf93>`
* Django 4.2 :commit:`(patch) <d0a82e26a74940bf0c78204933c3bdd6a283eb88>`
August 6, 2024 - :cve:`2024-41989`
----------------------------------
Potential memory exhaustion in ``django.utils.numberformat.floatformat()``.
`Full description
<https://www.djangoproject.com/weblog/2024/aug/06/security-releases/>`__
* Django 5.0 :commit:`(patch) <27900fe56f3d3cabb4aeb6ccb82f92bab29073a8>`
* Django 4.2 :commit:`(patch) <fc76660f589ac07e45e9cd34ccb8087aeb11904b>`
July 9, 2024 - :cve:`2024-39614`
--------------------------------

View File

@@ -141,6 +141,7 @@ Disqus
distro
django
djangoproject
djangotutorial
dm
docstring
docstrings

View File

@@ -400,10 +400,9 @@ the Django model that you wish to use as your user model.
Using a custom user model when starting a project
-------------------------------------------------
If you're starting a new project, it's highly recommended to set up a custom
user model, even if the default :class:`~django.contrib.auth.models.User` model
is sufficient for you. This model behaves identically to the default user
model, but you'll be able to customize it in the future if the need arises::
If you're starting a new project, you can set up a custom user model that
behaves identically to the default user model by subclassing
:class:`~django.contrib.auth.models.AbstractUser`::
from django.contrib.auth.models import AbstractUser
@@ -426,7 +425,7 @@ Changing to a custom user model mid-project
-------------------------------------------
Changing :setting:`AUTH_USER_MODEL` after you've created database tables is
significantly more difficult since it affects foreign keys and many-to-many
possible, but can be complex, since it affects foreign keys and many-to-many
relationships, for example.
This change can't be done automatically and requires manually fixing your
@@ -791,10 +790,17 @@ utility methods:
email address.
.. method:: models.BaseUserManager.get_by_natural_key(username)
.. method:: models.BaseUserManager.aget_by_natural_key(username)
*Asynchronous version*: ``aget_by_natural_key()``
Retrieves a user instance using the contents of the field
nominated by ``USERNAME_FIELD``.
.. versionchanged:: 5.2
``aget_by_natural_key()`` method was added.
Extending Django's default ``User``
-----------------------------------
@@ -1187,3 +1193,25 @@ Finally, specify the custom model as the default user model for your project
using the :setting:`AUTH_USER_MODEL` setting in your ``settings.py``::
AUTH_USER_MODEL = "customauth.MyUser"
.. _writing-authentication-backends-async-interface:
Adding an async interface
~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 5.2
To optimize performance when called from an async context authentication,
backends can implement async versions of each function - ``aget_user(user_id)``
and ``aauthenticate(request, **credentials)``. When an authentication backend
extends ``BaseBackend`` and async versions of these functions are not provided,
they will be automatically synthesized with ``sync_to_async``. This has
:ref:`performance penalties <async_performance>`.
While an async interface is optional, a synchronous interface is always
required. There is no automatic synthesis for a synchronous interface if an
async interface is implemented.
Django's out-of-the-box authentication backends have native async support. If
these native backends are extended take special care to make sure the async
versions of modified functions are modified as well.

View File

@@ -655,7 +655,7 @@ login view, may need to disable this behavior.
.. function:: login_not_required()
Allows unauthenticated requests without redirecting to the login page when
Allows unauthenticated requests to this view when
:class:`~django.contrib.auth.middleware.LoginRequiredMiddleware` is
installed.
@@ -1645,6 +1645,23 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`:
Option to disable (or reenable) password-based authentication was
added.
.. class:: AdminUserCreationForm
.. versionadded:: 5.1.1
A form used in the admin interface to create a new user. Inherits from
:class:`UserCreationForm`.
It includes an additional ``usable_password`` field, enabled by default. If
``usable_password`` is enabled, it verifies that ``password1`` and
``password2`` are non empty and match, validates the password using
:func:`~django.contrib.auth.password_validation.validate_password`, and
sets the user's password using
:meth:`~django.contrib.auth.models.User.set_password()`.
If ``usable_password`` is disabled, no password validation is done, and
password-based authentication is disabled for the user by calling
:meth:`~django.contrib.auth.models.User.set_unusable_password()`.
.. class:: AuthenticationForm
A form for logging a user in.
@@ -1691,6 +1708,18 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`:
code="no_b_users",
)
.. class:: BaseUserCreationForm
A :class:`~django.forms.ModelForm` for creating a new user. This is the
recommended base class if you need to customize the user creation form.
It has three fields: ``username`` (from the user model), ``password1``,
and ``password2``. It verifies that ``password1`` and ``password2`` match,
validates the password using
:func:`~django.contrib.auth.password_validation.validate_password`, and
sets the user's password using
:meth:`~django.contrib.auth.models.User.set_password()`.
.. class:: PasswordChangeForm
A form for allowing a user to change their password.
@@ -1703,7 +1732,9 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`:
.. method:: send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)
Uses the arguments to send an ``EmailMultiAlternatives``.
Can be overridden to customize how the email is sent to the user.
Can be overridden to customize how the email is sent to the user. If
you choose to override this method, be mindful of handling potential
exceptions raised due to email sending failures.
:param subject_template_name: the template for the subject.
:param email_template_name: the template for the email body.
@@ -1730,27 +1761,6 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`:
A form used in the admin interface to change a user's information and
permissions.
.. class:: BaseUserCreationForm
A :class:`~django.forms.ModelForm` for creating a new user. This is the
recommended base class if you need to customize the user creation form.
It has four fields: ``username`` (from the user model), ``password1``,
``password2``, and ``usable_password`` (the latter is enabled by default).
If ``usable_password`` is enabled, it verifies that ``password1`` and
``password2`` are non empty and match, validates the password using
:func:`~django.contrib.auth.password_validation.validate_password`, and
sets the user's password using
:meth:`~django.contrib.auth.models.User.set_password()`.
If ``usable_password`` is disabled, no password validation is done, and
password-based authentication is disabled for the user by calling
:meth:`~django.contrib.auth.models.User.set_unusable_password()`.
.. versionchanged:: 5.1
Option to create users with disabled password-based authentication was
added.
.. class:: UserCreationForm
Inherits from :class:`BaseUserCreationForm`. To help prevent confusion with

View File

@@ -273,3 +273,56 @@ works with an API-based workflow as well as 'normal' form POSTs::
class AuthorCreateView(JsonableResponseMixin, CreateView):
model = Author
fields = ["name"]
The above example assumes that if the client supports ``text/html``, that they
would prefer it. However, this may not always be true. When requesting a
``.css`` file, many browsers will send the header
``Accept: text/css,*/*;q=0.1``, indicating that they would prefer CSS, but
anything else is fine. This means ``request.accepts("text/html") will be
``True``.
To determine the correct format, taking into consideration the client's
preference, use :func:`django.http.HttpRequest.get_preferred_type`::
class JsonableResponseMixin:
"""
Mixin to add JSON support to a form.
Must be used with an object-based FormView (e.g. CreateView).
"""
accepted_media_types = ["text/html", "application/json"]
def dispatch(self, request, *args, **kwargs):
if request.get_preferred_type(self.accepted_media_types) is None:
# No format in common.
return HttpResponse(
status_code=406, headers={"Accept": ",".join(self.accepted_media_types)}
)
return super().dispatch(request, *args, **kwargs)
def form_invalid(self, form):
response = super().form_invalid(form)
accepted_type = request.get_preferred_type(self.accepted_media_types)
if accepted_type == "text/html":
return response
elif accepted_type == "application/json":
return JsonResponse(form.errors, status=400)
def form_valid(self, form):
# We make sure to call the parent's form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
response = super().form_valid(form)
accepted_type = request.get_preferred_type(self.accepted_media_types)
if accepted_type == "text/html":
return response
elif accepted_type == "application/json":
data = {
"pk": self.object.pk,
}
return JsonResponse(data)
.. versionchanged:: 5.2
The :meth:`.HttpRequest.get_preferred_type` method was added.

View File

@@ -720,6 +720,9 @@ Django places some restrictions on model field names:
#. A field name cannot end with an underscore, for similar reasons.
#. A field name cannot be ``check``, as this would override the check
framework's ``Model.check()`` method.
These limitations can be worked around, though, because your field name doesn't
necessarily have to match your database column name. See the
:attr:`~Field.db_column` option.
@@ -914,7 +917,7 @@ example::
if (
update_fields := kwargs.get("update_fields")
) is not None and "name" in update_fields:
update_fields = {"slug"}.union(update_fields)
kwargs["update_fields"] = {"slug"}.union(update_fields)
super().save(**kwargs)
See :ref:`ref-models-update-fields` for more details.

View File

@@ -14,7 +14,7 @@ As general programming practice, this goes without saying. Find out :ref:`what
queries you are doing and what they are costing you <faq-see-raw-sql-queries>`.
Use :meth:`.QuerySet.explain` to understand how specific ``QuerySet``\s are
executed by your database. You may also want to use an external project like
django-debug-toolbar_, or a tool that monitors your database directly.
:pypi:`django-debug-toolbar`, or a tool that monitors your database directly.
Remember that you may be optimizing for speed or memory or both, depending on
your requirements. Sometimes optimizing for one will be detrimental to the
@@ -30,8 +30,6 @@ readability of your code. **All** of the suggestions below come with the caveat
that in your circumstances the general principle might not apply, or might even
be reversed.
.. _django-debug-toolbar: https://github.com/jazzband/django-debug-toolbar/
Use standard DB optimization techniques
=======================================

View File

@@ -62,7 +62,8 @@ class represents a particular record in the database table.
To create an object, instantiate it using keyword arguments to the model class,
then call :meth:`~django.db.models.Model.save` to save it to the database.
Assuming models live in a file ``mysite/blog/models.py``, here's an example:
Assuming models live in a ``models.py`` file inside a ``blog`` Django app, here
is an example:
.. code-block:: pycon

View File

@@ -12,10 +12,11 @@ development, and to provide support for platforms that can't use SMTP.
The code lives in the ``django.core.mail`` module.
Quick example
=============
Quick examples
==============
In two lines::
Use :func:`send_mail` for straightforward email sending. For example, to send a
plain text message::
from django.core.mail import send_mail
@@ -27,6 +28,39 @@ In two lines::
fail_silently=False,
)
When additional email sending functionality is needed, use
:class:`EmailMessage` or :class:`EmailMultiAlternatives`. For example, to send
a multipart email that includes both HTML and plain text versions with a
specific template and custom headers, you can use the following approach::
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
# First, render the plain text content.
text_content = render_to_string(
"templates/emails/my_email.txt",
context={"my_variable": 42},
)
# Secondly, render the HTML content.
html_content = render_to_string(
"templates/emails/my_email.html",
context={"my_variable": 42},
)
# Then, create a multipart email instance.
msg = EmailMultiAlternatives(
"Subject here",
text_content,
"from@example.com",
["to@example.com"],
headers={"List-Unsubscribe": "<mailto:unsub@example.com>"},
)
# Lastly, attach the HTML content to the email instance and send.
msg.attach_alternative(html_content, "text/html")
msg.send()
Mail is sent using the SMTP host and port specified in the
:setting:`EMAIL_HOST` and :setting:`EMAIL_PORT` settings. The
:setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD` settings, if
@@ -282,13 +316,14 @@ All parameters are optional and can be set at any time prior to calling the
new connection is created when ``send()`` is called.
* ``attachments``: A list of attachments to put on the message. These can
be either :class:`~email.mime.base.MIMEBase` instances, or a named tuple
with attributes ``(filename, content, mimetype)``.
be instances of :class:`~email.mime.base.MIMEBase` or
:class:`~django.core.mail.EmailAttachment`, or a tuple with attributes
``(filename, content, mimetype)``.
.. versionchanged:: 5.2
In older versions, tuple items of ``attachments`` were regular tuples,
as opposed to named tuples.
Support for :class:`~django.core.mail.EmailAttachment` items of
``attachments`` were added.
* ``headers``: A dictionary of extra headers to put on the message. The
keys are the header name, values are the header values. It's up to the
@@ -384,6 +419,18 @@ The class has the following methods:
For MIME types starting with :mimetype:`text/`, binary data is handled as in
``attach()``.
.. class:: EmailAttachment
.. versionadded:: 5.2
A named tuple to store attachments to an email.
The named tuple has the following indexes:
* ``filename``
* ``content``
* ``mimetype``
Sending alternative content types
---------------------------------
@@ -404,20 +451,21 @@ Django's email library, you can do this using the
.. attribute:: alternatives
A list of named tuples with attributes ``(content, mimetype)``. This is
particularly useful in tests::
A list of :class:`~django.core.mail.EmailAlternative` named tuples. This
is particularly useful in tests::
self.assertEqual(len(msg.alternatives), 1)
self.assertEqual(msg.alternatives[0].content, html_content)
self.assertEqual(msg.alternatives[0].mimetype, "text/html")
Alternatives should only be added using the :meth:`attach_alternative`
method.
method, or passed to the constructor.
.. versionchanged:: 5.2
In older versions, ``alternatives`` was a list of regular tuples,
as opposed to named tuples.
as opposed to :class:`~django.core.mail.EmailAlternative` named
tuples.
.. method:: attach_alternative(content, mimetype)
@@ -456,6 +504,17 @@ Django's email library, you can do this using the
self.assertIs(msg.body_contains("I am content"), True)
self.assertIs(msg.body_contains("<p>I am content.</p>"), False)
.. class:: EmailAlternative
.. versionadded:: 5.2
A named tuple to store alternative versions of email content.
The named tuple has the following indexes:
* ``content``
* ``mimetype``
Updating the default content type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -749,7 +808,7 @@ to a file that can be inspected at your leisure.
Another approach is to use a "dumb" SMTP server that receives the emails
locally and displays them to the terminal, but does not actually send
anything. The `aiosmtpd`_ package provides a way to accomplish this:
anything. The :pypi:`aiosmtpd` package provides a way to accomplish this:
.. code-block:: shell

View File

@@ -1335,9 +1335,7 @@ whenever you restart your application server::
You can even pre-generate the JavaScript catalog as part of your deployment
procedure and serve it as a static file. This radical technique is implemented
in django-statici18n_.
.. _django-statici18n: https://django-statici18n.readthedocs.io/
in :pypi:`django-statici18n`.
.. _url-internationalization:
@@ -1553,7 +1551,7 @@ Django comes with a tool, :djadmin:`django-admin makemessages
commands from the GNU gettext toolset: ``xgettext``, ``msgfmt``,
``msgmerge`` and ``msguniq``.
The minimum version of the ``gettext`` utilities supported is 0.15.
The minimum version of the ``gettext`` utilities supported is 0.19.
To create or update a message file, run this command:

View File

@@ -55,11 +55,10 @@ code.
Django tools
~~~~~~~~~~~~
`django-debug-toolbar
<https://github.com/jazzband/django-debug-toolbar/>`_ is a very handy tool that
provides insights into what your code is doing and how much time it spends
doing it. In particular it can show you all the SQL queries your page is
generating, and how long each one has taken.
:pypi:`django-debug-toolbar` is a very handy tool that provides insights into
what your code is doing and how much time it spends doing it. In particular it
can show you all the SQL queries your page is generating, and how long each one
has taken.
Third-party panels are also available for the toolbar, that can (for example)
report on cache performance and template rendering times.

View File

@@ -347,6 +347,86 @@ again a mapping with the key being name of the field and the value the value:
Referential fields are again represented by the PK or sequence of PKs.
.. _custom-serialization-formats:
Custom serialization formats
----------------------------
In addition to the default formats, you can create a custom serialization
format.
For example, lets consider a csv serializer and deserializer. First, define a
``Serializer`` and a ``Deserializer`` class. These can override existing
serialization format classes:
.. code-block:: python
:caption: ``path/to/custom_csv_serializer.py``
import csv
from django.apps import apps
from django.core import serializers
from django.core.serializers.base import DeserializationError
class Serializer(serializers.python.Serializer):
def get_dump_object(self, obj):
dumped_object = super().get_dump_object(obj)
row = [dumped_object["model"], str(dumped_object["pk"])]
row += [str(value) for value in dumped_object["fields"].values()]
return ",".join(row), dumped_object["model"]
def end_object(self, obj):
dumped_object_str, model = self.get_dump_object(obj)
if self.first:
fields = [field.name for field in apps.get_model(model)._meta.fields]
header = ",".join(fields)
self.stream.write(f"model,{header}\n")
self.stream.write(f"{dumped_object_str}\n")
def getvalue(self):
return super(serializers.python.Serializer, self).getvalue()
class Deserializer(serializers.python.Deserializer):
def __init__(self, stream_or_string, **options):
if isinstance(stream_or_string, bytes):
stream_or_string = stream_or_string.decode()
if isinstance(stream_or_string, str):
stream_or_string = stream_or_string.splitlines()
try:
objects = csv.DictReader(stream_or_string)
except Exception as exc:
raise DeserializationError() from exc
super().__init__(objects, **options)
def _handle_object(self, obj):
try:
model_fields = apps.get_model(obj["model"])._meta.fields
obj["fields"] = {
field.name: obj[field.name]
for field in model_fields
if field.name in obj
}
yield from super()._handle_object(obj)
except (GeneratorExit, DeserializationError):
raise
except Exception as exc:
raise DeserializationError(f"Error deserializing object: {exc}") from exc
Then add the module containing the serializer definitions to your
:setting:`SERIALIZATION_MODULES` setting::
SERIALIZATION_MODULES = {
"csv": "path.to.custom_csv_serializer",
"json": "django.core.serializers.json",
}
.. versionchanged:: 5.2
A ``Deserializer`` class definition was added to each of the provided
serialization formats.
.. _topics-serialization-natural-keys:
Natural keys

View File

@@ -50,7 +50,7 @@ To sign a value, first instantiate a ``Signer`` instance:
>>> signer = Signer()
>>> value = signer.sign("My string")
>>> value
'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w'
'My string:v9G-nxfz3iQGTXrePqYPlGvH79WTcIgj1QIQSUODTW0'
The signature is appended to the end of the string, following the colon.
You can retrieve the original value using the ``unsign`` method:
@@ -79,7 +79,7 @@ If you wish to protect a list, tuple, or dictionary you can do so using the
>>> signed_obj = signer.sign_object({"message": "Hello!"})
>>> signed_obj
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:Xdc-mOFDjs22KsQAqfVfi8PQSPdo3ckWJxPWwQOFhR4'
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:bzb48DBkB-bwLaCnUVB75r5VAPUEpzWJPrTb80JMIXM'
>>> obj = signer.unsign_object(signed_obj)
>>> obj
{'message': 'Hello!'}
@@ -108,7 +108,7 @@ generate signatures. You can use a different secret by passing it to the
>>> signer = Signer(key="my-other-secret")
>>> value = signer.sign("My string")
>>> value
'My string:EkfQJafvGyiofrdGnuthdxImIJw'
'My string:o3DrrsT6JRB73t-HDymfDNbTSxfMlom2d8TiUlb1hWY'
.. class:: Signer(*, key=None, sep=':', salt=None, algorithm=None, fallback_keys=None)
@@ -132,13 +132,13 @@ your :setting:`SECRET_KEY`:
>>> signer = Signer()
>>> signer.sign("My string")
'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w'
'My string:v9G-nxfz3iQGTXrePqYPlGvH79WTcIgj1QIQSUODTW0'
>>> signer.sign_object({"message": "Hello!"})
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:Xdc-mOFDjs22KsQAqfVfi8PQSPdo3ckWJxPWwQOFhR4'
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:bzb48DBkB-bwLaCnUVB75r5VAPUEpzWJPrTb80JMIXM'
>>> signer = Signer(salt="extra")
>>> signer.sign("My string")
'My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw'
>>> signer.unsign("My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw")
'My string:YMD-FR6rof3heDkFRffdmG4pXbAZSOtb-aQxg3vmmfc'
>>> signer.unsign("My string:YMD-FR6rof3heDkFRffdmG4pXbAZSOtb-aQxg3vmmfc")
'My string'
>>> signer.sign_object({"message": "Hello!"})
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:-UWSLCE-oUAHzhkHviYz3SOZYBjFKllEOyVZNuUtM-I'
@@ -172,7 +172,7 @@ created within a specified period of time:
>>> signer = TimestampSigner()
>>> value = signer.sign("hello")
>>> value
'hello:1NMg5H:oPVuCqlJWmChm1rA2lyTUtelC-c'
'hello:1stLqR:_rvr4oXCgT4HyfwjXaU39QvTnuNuUthFRCzNOy4Hqt0'
>>> signer.unsign(value)
'hello'
>>> signer.unsign(value, max_age=10)
@@ -224,12 +224,12 @@ arbitrary commands by exploiting the pickle format:
>>> signer = signing.TimestampSigner()
>>> value = signer.sign_object({"foo": "bar"})
>>> value
'eyJmb28iOiJiYXIifQ:1kx6R3:D4qGKiptAqo5QW9iv4eNLc6xl4RwiFfes6oOcYhkYnc'
'eyJmb28iOiJiYXIifQ:1stLrZ:_QiOBHafwucBF9FyAr54qEs84ZO1UdsO1XiTJCvvdno'
>>> signer.unsign_object(value)
{'foo': 'bar'}
>>> value = signing.dumps({"foo": "bar"})
>>> value
'eyJmb28iOiJiYXIifQ:1kx6Rf:LBB39RQmME-SRvilheUe5EmPYRbuDBgQp2tCAi7KGLk'
'eyJmb28iOiJiYXIifQ:1stLsC:JItq2ZVjmAK6ivrWI-v1Gk1QVf2hOF52oaEqhZHca7I'
>>> signing.loads(value)
{'foo': 'bar'}

View File

@@ -280,6 +280,11 @@ To prevent serialized data from being loaded twice, setting
:data:`~django.db.models.signals.post_migrate` signal when flushing the test
database.
.. versionchanged:: 5.2
For :class:`TransactionTestCase`, serialized migration data is made
available during ``setUpClass()``.
Other test conditions
---------------------

View File

@@ -1262,25 +1262,35 @@ subclass::
Here's specifically what will happen:
* At the start of each test, before ``setUp()`` is run, Django will flush the
database, returning the database to the state it was in directly after
:djadmin:`migrate` was called.
* During ``setUpClass()``, all the named fixtures are installed. In this
example, Django will install any JSON fixture named ``mammals``, followed by
any fixture named ``birds``. See the :ref:`fixtures-explanation` topic for
more details on defining and installing fixtures.
* Then, all the named fixtures are installed. In this example, Django will
install any JSON fixture named ``mammals``, followed by any fixture named
``birds``. See the :ref:`fixtures-explanation` topic for more details on
defining and installing fixtures.
For most unit tests using :class:`TestCase`, Django doesn't need to do
anything else, because transactions are used to clean the database after each
test for performance reasons. But for :class:`TransactionTestCase`, the
following actions will take place:
For performance reasons, :class:`TestCase` loads fixtures once for the entire
test class, before :meth:`~TestCase.setUpTestData`, instead of before each
test, and it uses transactions to clean the database before each test. In any case,
you can be certain that the outcome of a test will not be affected by another
test or by the order of test execution.
* At the end of each test Django will flush the database, returning the
database to the state it was in directly after :djadmin:`migrate` was
called.
* For each subsequent test, the fixtures will be reloaded before ``setUp()``
is run.
In any case, you can be certain that the outcome of a test will not be
affected by another test or by the order of test execution.
By default, fixtures are only loaded into the ``default`` database. If you are
using multiple databases and set :attr:`TransactionTestCase.databases`,
fixtures will be loaded into all specified databases.
.. versionchanged:: 5.2
For :class:`TransactionTestCase`, fixtures were made available during
``setUpClass()``.
URLconf configuration
---------------------