Compare commits

...

33 Commits

Author SHA1 Message Date
Piotr Kawula
7732573126
Merge 268c71f2d7 into a627194567 2025-08-31 00:35:01 +09:00
Jacob Walls
a627194567
Refs #36485 -- Corrected docs linter to detect too-long lines at file end. 2025-08-29 17:35:50 -04:00
SaJH
bb7a7701b1 Fixed #36431 -- Returned tuples for multi-column ForeignObject in values()/values_list().
Thanks Jacob Walls and Simon Charette for tests.

Signed-off-by: SaJH <wogur981208@gmail.com>
2025-08-29 15:33:44 -04:00
Jacob Walls
2d453a2a68 Refs #36152 -- Suppressed duplicate warning when using "%" in alias via values(). 2025-08-29 13:45:08 -04:00
Mustafa Pirbhai
183fcebf88 Fixed #35831 -- Documented the model form meta API in model form reference docs.
Co-authored-by: Jonathan <3218047+jernwerber@users.noreply.github.com>
Co-authored-by: Mustafa <117516335+mspirbhai@users.noreply.github.com>
2025-08-29 08:58:58 +02:00
SaJH
eaaf01c96a Refs #34624 -- Changed RedirectAdmin to use a Select widget for the site field.
Signed-off-by: SaJH <wogur981208@gmail.com>
2025-08-29 08:38:12 +02:00
SaJH
0be1c4575b Fixed #34624 -- Removed change, delete, and view buttons for non-Select widgets in RelatedFieldWidgetWrapper.
Signed-off-by: SaJH <wogur981208@gmail.com>
2025-08-29 08:38:12 +02:00
Rob Hudson
550822bcee Fixed #36532 -- Added Content Security Policy view decorators to override or disable policies.
Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
2025-08-28 17:23:48 -03:00
Simon Charette
292b9e6fe8 Refs #27222 -- Adapted RETURNING handling to be usable for UPDATE queries.
Renamed existing methods and abstractions used for INSERT … RETURNING
to be generic enough to be used in the context of UPDATEs as well.

This also consolidates SQL compliant implementations on
BaseDatabaseOperations.
2025-08-28 20:44:21 +02:00
Simon Charette
dc4ee99152 Refs #27222 -- Implemented BaseDatabaseOperations.return_insert_columns()/fetch_returned_insert_rows(). 2025-08-28 20:44:21 +02:00
Jake Howard
41ff30f6f9 Refs #36520 -- Ensured only the header value is passed to parse_header_parameters for multipart requests.
Header parsing should apply only to the header value. The previous
implementation happened to work but relied on unintended behavior.
2025-08-28 14:25:36 -03:00
David Smith
c93dddf659 Added sphinxlint checker to flag relative targets in :doc: roles.
Co-authored-by: Adam Johnson <me@adamj.eu>
2025-08-28 13:48:32 -03:00
Adam Johnson
56955636e6 Ensured :doc: role uses absolute targets in docs. 2025-08-28 13:48:32 -03:00
Natalia
ae03f81ffa Replaced :doc: role usage with :ref: when appropriate in docs. 2025-08-28 13:48:32 -03:00
SaJH
a9fe98d5bd Fixed #35533 -- Prevented urlize creating broken links given a markdown link input.
Signed-off-by: SaJH <wogur981208@gmail.com>
2025-08-28 08:54:56 +02:00
David Smith
05bac8c420 Refs #36570 -- Added sphinxlint checker to flag unnecessary :py domain in documentation roles. 2025-08-28 08:52:43 +02:00
SaJH
3c0c54351b Fixed #36570 -- Removed unnecessary :py domain from documentation roles.
Signed-off-by: SaJH <wogur981208@gmail.com>
2025-08-28 08:52:43 +02:00
Tim Graham
1285de557b Fixed incorrect IDs in test_in_bulk_preserve_ordering. 2025-08-27 18:23:42 -04:00
Adam Johnson
d8426f64a7 Fixed #36577 -- Removed obsolete try-except for GIS layermapping imports. 2025-08-27 13:16:28 -03:00
Natalia
4f07767106 Added matrix with newer image versions to the "postgis" GitHub Action.
This work allows to test three types of postgis Docker images to cover
a wider spectrum of geo libraries versions:

* `latest` (recommended upstream): uses latest stable Debian packages.
  These versions are generally conservative, so they may lag behind.
* `alpine`: build PostGIS from source on Alpine, and ship newer
  geospatial libs.
* `master`: provides development versions, therefore coverage for what's
  coming. Future compatibility issues can be caught in advance.

This split is important because each image differs significantly in
GEOS/PROJ/GDAL versions, so testing all increases confidence in
compatibility. More info at https://hub.docker.com/r/postgis/postgis/.

For example, at the time of this branch:

* latest stable in debian:
  * POSTGIS="3.5.2 dea6d0a"
  * GEOS="3.9.0-CAPI-1.16.2"
  * PROJ="7.2.1"
* latest stable in alpine:
  * POSTGIS="3.5.3 0"
  * GEOS="3.13.1-CAPI-1.19.2"
  * PROJ="9.6.0
* latest development branch:
  * POSTGIS="3.6.0dev 3.6.0beta1-29-g7c8cfe07d"
  * GEOS="3.14.0beta2-CAPI-1.20.1"
  * PROJ="9.7.0"
2025-08-27 11:33:13 -03:00
Natalia
1b0c4d5ea5 Ensured apt repo is updated before installing deps in "postgis" GitHub Action. 2025-08-27 11:33:13 -03:00
Sarah Boyce
4c71e33440 Added stub release notes and release date for 5.2.6, 5.1.12, and 4.2.24. 2025-08-27 16:01:20 +02:00
Sarah Boyce
d0e4dd5cdd Fixed #36572 -- Revert "Fixed #36546 -- Deprecated django.utils.crypto.constant_time_compare() in favor of hmac.compare_digest()."
This reverts commit 0246f47888.
2025-08-27 10:50:50 +02:00
Jacob Walls
c594574175 Clarified Trac "version" attribute in contributing guide. 2025-08-26 17:49:06 -04:00
Jacob Walls
d454aefbd1
Refs #15727 -- Captured failed request log in CSPMiddlewareTest. 2025-08-26 17:26:01 -04:00
Jacob Walls
66082a7dac
Corrected definition of "needsinfo" triage stage in contributing guide. 2025-08-26 16:00:47 -04:00
David Smith
07f44c9e9a Fixed #36568 -- Confirmed support for GEOS 3.14. 2025-08-26 16:01:41 -03:00
Piotr Kawula
268c71f2d7
Update django/views/templates/i18n_catalog.js
Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
2024-04-25 14:00:59 +02:00
Piotr Kawula
d3b92d0bbd Fixed #35278 - Fixed passing four arguments (instead of three) to test function. 2024-03-11 08:51:26 +01:00
Piotr Kawula
a9830a403b Fixed #35278 -- Fixed tests for fallback translations key when catalog has empty array on provided . 2024-03-07 12:39:55 +01:00
Piotr Kawula
c39c7133a0 Fixed #35278 -- Refactored and functions to use helper function with extracted common logic. 2024-03-07 12:34:28 +01:00
Piotr Kawula
54fa8b5693 Fixed #35278 -- Tested fixed versions of and functions. 2024-03-07 11:11:59 +01:00
Piotr Kawula
76f4b0c0f3 Fixed #35278 -- Fixed returning possibly undefined from and functions. 2024-03-07 09:36:41 +01:00
121 changed files with 1281 additions and 603 deletions

View File

@ -14,13 +14,17 @@ permissions:
contents: read
jobs:
postgis-latest:
postgis:
if: contains(github.event.pull_request.labels.*.name, 'geodjango')
runs-on: ubuntu-latest
name: Latest PostGIS
strategy:
fail-fast: false
matrix:
postgis-version: [latest, "17-3.5-alpine", "17-master"]
name: PostGIS ${{ matrix.postgis-version }}
services:
postgres:
image: postgis/postgis:latest
image: postgis/postgis:${{ matrix.postgis-version }}
env:
POSTGRES_DB: geodjango
POSTGRES_USER: user
@ -41,8 +45,10 @@ jobs:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: 'tests/requirements/py3.txt'
- name: Update apt repo
run: sudo apt update
- name: Install libmemcached-dev for pylibmc
run: sudo apt install libmemcached-dev
run: sudo apt install -y libmemcached-dev
- name: Install geospatial dependencies
run: sudo apt install -y binutils libproj-dev gdal-bin
- name: Print PostGIS versions

View File

@ -10,6 +10,7 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import URLValidator
from django.db.models import CASCADE, UUIDField
from django.forms.widgets import Select
from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
from django.utils.html import smart_urlquote
@ -284,16 +285,18 @@ class RelatedFieldWidgetWrapper(forms.Widget):
if can_add_related is None:
can_add_related = admin_site.is_registered(rel.model)
self.can_add_related = can_add_related
# XXX: The UX does not support multiple selected values.
multiple = getattr(widget, "allow_multiple_selected", False)
if not isinstance(widget, AutocompleteMixin):
self.attrs["data-context"] = "available-source"
self.can_change_related = not multiple and can_change_related
# Only single-select Select widgets are supported.
supported = not getattr(
widget, "allow_multiple_selected", False
) and isinstance(widget, Select)
self.can_change_related = supported and can_change_related
# XXX: The deletion UX can be confusing when dealing with cascading
# deletion.
cascade = getattr(rel, "on_delete", None) is CASCADE
self.can_delete_related = not multiple and not cascade and can_delete_related
self.can_view_related = not multiple and can_view_related
self.can_delete_related = supported and not cascade and can_delete_related
self.can_view_related = supported and can_view_related
# To check if the related object is registered with this AdminSite.
self.admin_site = admin_site
self.use_fieldset = True

View File

@ -1,4 +1,3 @@
import hmac
import inspect
import re
import warnings
@ -7,6 +6,7 @@ from django.apps import apps as django_apps
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.middleware.csrf import rotate_token
from django.utils.crypto import constant_time_compare
from django.utils.deprecation import RemovedInDjango61Warning
from django.utils.module_loading import import_string
from django.views.decorators.debug import sensitive_variables
@ -175,7 +175,7 @@ def login(request, user, backend=None):
if SESSION_KEY in request.session:
if _get_user_session_key(request) != user.pk or (
session_auth_hash
and not hmac.compare_digest(
and not constant_time_compare(
request.session.get(HASH_SESSION_KEY, ""), session_auth_hash
)
):
@ -217,7 +217,7 @@ async def alogin(request, user, backend=None):
if await request.session.ahas_key(SESSION_KEY):
if await _aget_user_session_key(request) != user.pk or (
session_auth_hash
and not hmac.compare_digest(
and not constant_time_compare(
await request.session.aget(HASH_SESSION_KEY, ""),
session_auth_hash,
)
@ -323,7 +323,7 @@ def get_user(request):
session_hash_verified = False
else:
session_auth_hash = user.get_session_auth_hash()
session_hash_verified = hmac.compare_digest(
session_hash_verified = constant_time_compare(
session_hash, session_auth_hash
)
if not session_hash_verified:
@ -331,7 +331,7 @@ def get_user(request):
# with the fallback secrets and stop when a matching one is
# found.
if session_hash and any(
hmac.compare_digest(session_hash, fallback_auth_hash)
constant_time_compare(session_hash, fallback_auth_hash)
for fallback_auth_hash in user.get_session_auth_fallback_hash()
):
request.session.cycle_key()
@ -364,7 +364,7 @@ async def aget_user(request):
session_hash_verified = False
else:
session_auth_hash = user.get_session_auth_hash()
session_hash_verified = hmac.compare_digest(
session_hash_verified = constant_time_compare(
session_hash, session_auth_hash
)
if not session_hash_verified:
@ -372,7 +372,7 @@ async def aget_user(request):
# with the fallback secrets and stop when a matching one is
# found.
if session_hash and any(
hmac.compare_digest(session_hash, fallback_auth_hash)
constant_time_compare(session_hash, fallback_auth_hash)
for fallback_auth_hash in user.get_session_auth_fallback_hash()
):
await request.session.acycle_key()

View File

@ -2,7 +2,6 @@ import base64
import binascii
import functools
import hashlib
import hmac
import importlib
import math
import warnings
@ -13,7 +12,12 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.signals import setting_changed
from django.dispatch import receiver
from django.utils.crypto import RANDOM_STRING_CHARS, get_random_string, pbkdf2
from django.utils.crypto import (
RANDOM_STRING_CHARS,
constant_time_compare,
get_random_string,
pbkdf2,
)
from django.utils.encoding import force_bytes, force_str
from django.utils.module_loading import import_string
from django.utils.translation import gettext_noop as _
@ -345,7 +349,7 @@ class PBKDF2PasswordHasher(BasePasswordHasher):
def verify(self, password, encoded):
decoded = self.decode(encoded)
encoded_2 = self.encode(password, decoded["salt"], decoded["iterations"])
return hmac.compare_digest(encoded, encoded_2)
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
decoded = self.decode(encoded)
@ -529,7 +533,7 @@ class BCryptSHA256PasswordHasher(BasePasswordHasher):
algorithm, data = encoded.split("$", 1)
assert algorithm == self.algorithm
encoded_2 = self.encode(password, data.encode("ascii"))
return hmac.compare_digest(encoded, encoded_2)
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
decoded = self.decode(encoded)
@ -624,7 +628,7 @@ class ScryptPasswordHasher(BasePasswordHasher):
decoded["block_size"],
decoded["parallelism"],
)
return hmac.compare_digest(encoded, encoded_2)
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
decoded = self.decode(encoded)
@ -677,7 +681,7 @@ class MD5PasswordHasher(BasePasswordHasher):
def verify(self, password, encoded):
decoded = self.decode(encoded)
encoded_2 = self.encode(password, decoded["salt"])
return hmac.compare_digest(encoded, encoded_2)
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
decoded = self.decode(encoded)

View File

@ -1,8 +1,7 @@
import hmac
from datetime import datetime
from django.conf import settings
from django.utils.crypto import salted_hmac
from django.utils.crypto import constant_time_compare, salted_hmac
from django.utils.http import base36_to_int, int_to_base36
@ -68,7 +67,7 @@ class PasswordResetTokenGenerator:
# Check that the timestamp/uid has not been tampered with
for secret in [self.secret, *self.secret_fallbacks]:
if hmac.compare_digest(
if constant_time_compare(
self._make_token_with_timestamp(user, ts, secret),
token,
):

View File

@ -2,24 +2,16 @@
This module contains useful utilities for GeoDjango.
"""
from django.contrib.gis.utils.layermapping import LayerMapError, LayerMapping
from django.contrib.gis.utils.ogrinfo import ogrinfo
from django.contrib.gis.utils.ogrinspect import mapping, ogrinspect
from django.contrib.gis.utils.srs import add_srs_entry
from django.core.exceptions import ImproperlyConfigured
__all__ = [
"add_srs_entry",
"mapping",
"ogrinfo",
"ogrinspect",
"LayerMapError",
"LayerMapping",
]
try:
# LayerMapping requires DJANGO_SETTINGS_MODULE to be set,
# and ImproperlyConfigured is raised if that's not the case.
from django.contrib.gis.utils.layermapping import LayerMapError, LayerMapping
__all__ += ["LayerMapError", "LayerMapping"]
except ImproperlyConfigured:
pass

View File

@ -7,4 +7,3 @@ class RedirectAdmin(admin.ModelAdmin):
list_display = ("old_path", "new_path")
list_filter = ("site",)
search_fields = ("old_path", "new_path")
radio_fields = {"site": admin.VERTICAL}

View File

@ -36,13 +36,12 @@ These functions make use of all of them.
import base64
import datetime
import hmac
import json
import time
import zlib
from django.conf import settings
from django.utils.crypto import salted_hmac
from django.utils.crypto import constant_time_compare, salted_hmac
from django.utils.encoding import force_bytes
from django.utils.module_loading import import_string
from django.utils.regex_helper import _lazy_re_compile
@ -210,7 +209,7 @@ class Signer:
raise BadSignature('No "%s" found in value' % self.sep)
value, sig = signed_value.rsplit(self.sep, 1)
for key in [self.key, *self.fallback_keys]:
if hmac.compare_digest(sig, self.signature(value, key)):
if constant_time_compare(sig, self.signature(value, key)):
return value
raise BadSignature('Signature "%s" does not match' % sig)

View File

@ -208,13 +208,6 @@ class BaseDatabaseOperations:
else:
return ["DISTINCT"], []
def fetch_returned_insert_columns(self, cursor, returning_params):
"""
Given a cursor object that has just performed an INSERT...RETURNING
statement into a table, return the newly created data.
"""
return cursor.fetchone()
def force_group_by(self):
"""
Return a GROUP BY clause to use with a HAVING clause when no grouping
@ -358,13 +351,31 @@ class BaseDatabaseOperations:
"""
return value
def return_insert_columns(self, fields):
def returning_columns(self, fields):
"""
For backends that support returning columns as part of an insert query,
return the SQL and params to append to the INSERT query. The returned
fragment should contain a format string to hold the appropriate column.
For backends that support returning columns as part of an insert or
update query, return the SQL and params to append to the query.
The returned fragment should contain a format string to hold the
appropriate column.
"""
pass
if not fields:
return "", ()
columns = [
"%s.%s"
% (
self.quote_name(field.model._meta.db_table),
self.quote_name(field.column),
)
for field in fields
]
return "RETURNING %s" % ", ".join(columns), ()
def fetch_returned_rows(self, cursor, returning_params):
"""
Given a cursor object for a DML query with a RETURNING statement,
return the selected returning rows of tuples.
"""
return cursor.fetchall()
def compiler(self, compiler_name):
"""

View File

@ -148,13 +148,6 @@ class DatabaseOperations(BaseDatabaseOperations):
else:
return f"TIME({sql})", params
def fetch_returned_insert_rows(self, cursor):
"""
Given a cursor object that has just performed an INSERT...RETURNING
statement into a table, return the tuple of returned data.
"""
return cursor.fetchall()
def format_for_duration_arithmetic(self, sql):
return "INTERVAL %s MICROSECOND" % sql
@ -182,20 +175,6 @@ class DatabaseOperations(BaseDatabaseOperations):
return name # Quoting once is enough.
return "`%s`" % name
def return_insert_columns(self, fields):
# MySQL doesn't support an INSERT...RETURNING statement.
if not fields:
return "", ()
columns = [
"%s.%s"
% (
self.quote_name(field.model._meta.db_table),
self.quote_name(field.column),
)
for field in fields
]
return "RETURNING %s" % ", ".join(columns), ()
def sql_flush(self, style, tables, *, reset_sequences=False, allow_cascade=False):
if not tables:
return []

View File

@ -22,7 +22,7 @@ from django.utils.functional import cached_property
from django.utils.regex_helper import _lazy_re_compile
from .base import Database
from .utils import BulkInsertMapper, InsertVar, Oracle_datetime
from .utils import BoundVar, BulkInsertMapper, Oracle_datetime
class DatabaseOperations(BaseDatabaseOperations):
@ -298,12 +298,27 @@ END;
def deferrable_sql(self):
return " DEFERRABLE INITIALLY DEFERRED"
def fetch_returned_insert_columns(self, cursor, returning_params):
columns = []
for param in returning_params:
value = param.get_value()
columns.append(value[0])
return tuple(columns)
def returning_columns(self, fields):
if not fields:
return "", ()
field_names = []
params = []
for field in fields:
field_names.append(
"%s.%s"
% (
self.quote_name(field.model._meta.db_table),
self.quote_name(field.column),
)
)
params.append(BoundVar(field))
return "RETURNING %s INTO %s" % (
", ".join(field_names),
", ".join(["%s"] * len(params)),
), tuple(params)
def fetch_returned_rows(self, cursor, returning_params):
return list(zip(*(param.get_value() for param in returning_params)))
def no_limit_value(self):
return None
@ -391,25 +406,6 @@ END;
match_option = "'i'"
return "REGEXP_LIKE(%%s, %%s, %s)" % match_option
def return_insert_columns(self, fields):
if not fields:
return "", ()
field_names = []
params = []
for field in fields:
field_names.append(
"%s.%s"
% (
self.quote_name(field.model._meta.db_table),
self.quote_name(field.column),
)
)
params.append(InsertVar(field))
return "RETURNING %s INTO %s" % (
", ".join(field_names),
", ".join(["%s"] * len(params)),
), tuple(params)
def __foreign_key_constraints(self, table_name, recursive):
with self.connection.cursor() as cursor:
if recursive:

View File

@ -4,7 +4,7 @@ import decimal
from .base import Database
class InsertVar:
class BoundVar:
"""
A late-binding cursor variable that can be passed to Cursor.execute
as a parameter, in order to receive the id of the row created by an

View File

@ -155,13 +155,6 @@ class DatabaseOperations(BaseDatabaseOperations):
return f"SELECT * FROM {placeholder_rows}"
return super().bulk_insert_sql(fields, placeholder_rows)
def fetch_returned_insert_rows(self, cursor):
"""
Given a cursor object that has just performed an INSERT...RETURNING
statement into a table, return the tuple of returned data.
"""
return cursor.fetchall()
def lookup_cast(self, lookup_type, internal_type=None):
lookup = "%s"
# Cast text lookups to text to allow things like filter(x__contains=4)
@ -324,19 +317,6 @@ class DatabaseOperations(BaseDatabaseOperations):
return cursor.query.decode()
return None
def return_insert_columns(self, fields):
if not fields:
return "", ()
columns = [
"%s.%s"
% (
self.quote_name(field.model._meta.db_table),
self.quote_name(field.column),
)
for field in fields
]
return "RETURNING %s" % ", ".join(columns), ()
if is_psycopg3:
def adapt_integerfield_value(self, value, internal_type):

View File

@ -84,13 +84,6 @@ class DatabaseOperations(BaseDatabaseOperations):
"""
return f"django_date_extract(%s, {sql})", (lookup_type.lower(), *params)
def fetch_returned_insert_rows(self, cursor):
"""
Given a cursor object that has just performed an INSERT...RETURNING
statement into a table, return the list of returned data.
"""
return cursor.fetchall()
def format_for_duration_arithmetic(self, sql):
"""Do nothing since formatting is handled in the custom function."""
return sql
@ -399,20 +392,6 @@ class DatabaseOperations(BaseDatabaseOperations):
return "INSERT OR IGNORE INTO"
return super().insert_statement(on_conflict=on_conflict)
def return_insert_columns(self, fields):
# SQLite < 3.35 doesn't support an INSERT...RETURNING statement.
if not fields:
return "", ()
columns = [
"%s.%s"
% (
self.quote_name(field.model._meta.db_table),
self.quote_name(field.column),
)
for field in fields
]
return "RETURNING %s" % ", ".join(columns), ()
def on_conflict_suffix_sql(self, fields, on_conflict, update_fields, unique_fields):
if (
on_conflict == OnConflict.UPDATE

View File

@ -35,6 +35,7 @@ from django.db.models.utils import (
resolve_callables,
)
from django.utils import timezone
from django.utils.deprecation import RemovedInDjango70Warning
from django.utils.functional import cached_property
# The maximum number of results to fetch in a get() query.
@ -1394,7 +1395,12 @@ class QuerySet(AltersData):
def _values(self, *fields, **expressions):
clone = self._chain()
if expressions:
clone = clone.annotate(**expressions)
# RemovedInDjango70Warning: When the deprecation ends, deindent as:
# clone = clone.annotate(**expressions)
with warnings.catch_warnings(
action="ignore", category=RemovedInDjango70Warning
):
clone = clone.annotate(**expressions)
clone._fields = fields
clone.query.set_values(fields)
return clone

View File

@ -1890,7 +1890,7 @@ class SQLInsertCompiler(SQLCompiler):
result.append(on_conflict_suffix_sql)
# Skip empty r_sql to allow subclasses to customize behavior for
# 3rd party backends. Refs #19096.
r_sql, self.returning_params = self.connection.ops.return_insert_columns(
r_sql, self.returning_params = self.connection.ops.returning_columns(
self.returning_fields
)
if r_sql:
@ -1925,20 +1925,16 @@ class SQLInsertCompiler(SQLCompiler):
cursor.execute(sql, params)
if not self.returning_fields:
return []
obj_len = len(self.query.objs)
if (
self.connection.features.can_return_rows_from_bulk_insert
and len(self.query.objs) > 1
and obj_len > 1
) or (
self.connection.features.can_return_columns_from_insert and obj_len == 1
):
rows = self.connection.ops.fetch_returned_insert_rows(cursor)
cols = [field.get_col(opts.db_table) for field in self.returning_fields]
elif self.connection.features.can_return_columns_from_insert:
assert len(self.query.objs) == 1
rows = [
self.connection.ops.fetch_returned_insert_columns(
cursor,
self.returning_params,
)
]
rows = self.connection.ops.fetch_returned_rows(
cursor, self.returning_params
)
cols = [field.get_col(opts.db_table) for field in self.returning_fields]
elif returning_fields and isinstance(
returning_field := returning_fields[0], AutoField

View File

@ -1219,7 +1219,7 @@ class Query(BaseExpression):
if "aggregate" in {frame.function for frame in inspect.stack()}:
stacklevel = 5
else:
# annotate() and alias().
# annotate(), alias(), and values().
stacklevel = 6
warnings.warn(
"Using percent signs in a column alias is deprecated.",
@ -2269,8 +2269,21 @@ class Query(BaseExpression):
join_info.joins,
join_info.path,
)
for target in targets:
cols.append(join_info.transform_function(target, final_alias))
if len(targets) > 1:
transformed_targets = [
join_info.transform_function(target, final_alias)
for target in targets
]
cols.append(
ColPairs(
final_alias if self.alias_cols else None,
[col.target for col in transformed_targets],
[col.output_field for col in transformed_targets],
join_info.final_field,
)
)
else:
cols.append(join_info.transform_function(targets[0], final_alias))
if cols:
self.set_select(cols)
except MultiJoin:

View File

@ -721,11 +721,10 @@ def parse_boundary_stream(stream, max_header_size):
# Eliminate blank lines
for line in header.split(b"\r\n"):
# This terminology ("main value" and "dictionary of
# parameters") is from the Python docs.
try:
main_value_pair, params = parse_header_parameters(line.decode())
name, value = main_value_pair.split(":", 1)
header_name, value_and_params = line.decode().split(":", 1)
name = header_name.lower().rstrip(" ")
value, params = parse_header_parameters(value_and_params.lstrip(" "))
params = {k: v.encode() for k, v in params.items()}
except ValueError: # Invalid header.
continue

View File

@ -1,5 +1,3 @@
from http import HTTPStatus
from django.conf import settings
from django.utils.csp import CSP, LazyNonce, build_policy
from django.utils.deprecation import MiddlewareMixin
@ -14,22 +12,21 @@ class ContentSecurityPolicyMiddleware(MiddlewareMixin):
request._csp_nonce = LazyNonce()
def process_response(self, request, response):
# In DEBUG mode, exclude CSP headers for specific status codes that
# trigger the debug view.
exempted_status_codes = {
HTTPStatus.NOT_FOUND,
HTTPStatus.INTERNAL_SERVER_ERROR,
}
if settings.DEBUG and response.status_code in exempted_status_codes:
return response
nonce = get_nonce(request)
sentinel = object()
if (csp_config := getattr(response, "_csp_config", sentinel)) is sentinel:
csp_config = settings.SECURE_CSP
if (csp_ro_config := getattr(response, "_csp_ro_config", sentinel)) is sentinel:
csp_ro_config = settings.SECURE_CSP_REPORT_ONLY
for header, config in [
(CSP.HEADER_ENFORCE, settings.SECURE_CSP),
(CSP.HEADER_REPORT_ONLY, settings.SECURE_CSP_REPORT_ONLY),
(CSP.HEADER_ENFORCE, csp_config),
(CSP.HEADER_REPORT_ONLY, csp_ro_config),
]:
# If headers are already set on the response, don't overwrite them.
# This allows for views to set their own CSP headers as needed.
# An empty config means CSP headers are not added to the response.
if config and header not in response:
response.headers[str(header)] = build_policy(config, nonce)

View File

@ -5,7 +5,6 @@ This module provides a middleware that implements protection
against request forgeries from other sites.
"""
import hmac
import logging
import string
from collections import defaultdict
@ -16,7 +15,7 @@ from django.core.exceptions import DisallowedHost, ImproperlyConfigured
from django.http import HttpHeaders, UnreadablePostError
from django.urls import get_callable
from django.utils.cache import patch_vary_headers
from django.utils.crypto import get_random_string
from django.utils.crypto import constant_time_compare, get_random_string
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import cached_property
from django.utils.http import is_same_domain
@ -155,7 +154,7 @@ def _does_token_match(request_csrf_token, csrf_secret):
if len(request_csrf_token) == CSRF_TOKEN_LENGTH:
request_csrf_token = _unmask_cipher_token(request_csrf_token)
assert len(request_csrf_token) == CSRF_SECRET_LENGTH
return hmac.compare_digest(request_csrf_token, csrf_secret)
return constant_time_compare(request_csrf_token, csrf_secret)
class RejectRequest(Exception):

View File

@ -5,10 +5,8 @@ Django's standard crypto functions and utilities.
import hashlib
import hmac
import secrets
import warnings
from django.conf import settings
from django.utils.deprecation import RemovedInDjango70Warning
from django.utils.encoding import force_bytes
@ -66,12 +64,7 @@ def get_random_string(length, allowed_chars=RANDOM_STRING_CHARS):
def constant_time_compare(val1, val2):
"""Return True if the two strings are equal, False otherwise."""
warnings.warn(
"constant_time_compare() is deprecated. Use hmac.compare_digest() instead.",
RemovedInDjango70Warning,
stacklevel=2,
)
return hmac.compare_digest(val1, val2)
return secrets.compare_digest(force_bytes(val1), force_bytes(val2))
def pbkdf2(password, salt, iterations, dklen=0, digest=None):

View File

@ -10,7 +10,7 @@ from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit, urlunsp
from django.conf import settings
from django.core.exceptions import SuspiciousOperation, ValidationError
from django.core.validators import EmailValidator
from django.core.validators import DomainNameValidator, EmailValidator
from django.utils.deprecation import RemovedInDjango70Warning
from django.utils.functional import Promise, cached_property, keep_lazy, keep_lazy_text
from django.utils.http import MAX_URL_LENGTH, RFC3986_GENDELIMS, RFC3986_SUBDELIMS
@ -296,7 +296,9 @@ class Urlizer:
simple_url_re = _lazy_re_compile(r"^https?://\[?\w", re.IGNORECASE)
simple_url_2_re = _lazy_re_compile(
r"^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$", re.IGNORECASE
rf"^www\.|^(?!http)(?:{DomainNameValidator.hostname_re})"
r"\.(com|edu|gov|int|mil|net|org)($|/.*)$",
re.IGNORECASE,
)
word_split_re = _lazy_re_compile(r"""([\s<>"']+)""")

View File

@ -18,6 +18,7 @@ from django.utils.encoding import force_str
from django.utils.module_loading import import_string
from django.utils.regex_helper import _lazy_re_compile
from django.utils.version import get_docs_version
from django.views.decorators.csp import csp_override, csp_report_only_override
from django.views.decorators.debug import coroutine_functions_to_sensitive_variables
# Minimal Django templates engine to render the error templates
@ -59,6 +60,8 @@ class CallableSettingWrapper:
return repr(self._wrapped)
@csp_override({})
@csp_report_only_override({})
def technical_500_response(request, exc_type, exc_value, tb, status_code=500):
"""
Create a technical server error response. The last three arguments are
@ -606,6 +609,8 @@ class ExceptionReporter:
tb = tb.tb_next
@csp_override({})
@csp_report_only_override({})
def technical_404_response(request, exception):
"""Create a technical 404 error response. `exception` is the Http404."""
try:

View File

@ -0,0 +1,39 @@
from functools import wraps
from asgiref.sync import iscoroutinefunction
def _make_csp_decorator(config_attr_name, config_attr_value):
"""General CSP override decorator factory."""
if not isinstance(config_attr_value, dict):
raise TypeError("CSP config should be a mapping.")
def decorator(view_func):
@wraps(view_func)
async def _wrapped_async_view(request, *args, **kwargs):
response = await view_func(request, *args, **kwargs)
setattr(response, config_attr_name, config_attr_value)
return response
@wraps(view_func)
def _wrapped_sync_view(request, *args, **kwargs):
response = view_func(request, *args, **kwargs)
setattr(response, config_attr_name, config_attr_value)
return response
if iscoroutinefunction(view_func):
return _wrapped_async_view
return _wrapped_sync_view
return decorator
def csp_override(config):
"""Override the Content-Security-Policy header for a view."""
return _make_csp_decorator("_csp_config", config)
def csp_report_only_override(config):
"""Override the Content-Security-Policy-Report-Only header for a view."""
return _make_csp_decorator("_csp_ro_config", config)

View File

@ -27,22 +27,40 @@
}
{% endif %}
function getValueFromCatalog(msgid, index) {
const value = django.catalog[msgid];
// if value in catalog is a string, return it
if (typeof value === 'string' && value) {
return value;
}
// if value in catalog is an array and index is present, return the array index if exists
if (value && value.constructor === Array && index !== undefined) {
const text = value[index];
if (typeof text === 'string' && text) {
return text;
}
}
return undefined;
}
if (!django.jsi18n_initialized) {
django.gettext = function(msgid) {
const value = django.catalog[msgid];
if (typeof value === 'undefined') {
return msgid;
} else {
return (typeof value === 'string') ? value : value[0];
}
const value = getValueFromCatalog(msgid, 0);
return value !== undefined ? value : msgid;
};
django.ngettext = function(singular, plural, count) {
const value = django.catalog[singular];
if (typeof value === 'undefined') {
return (count == 1) ? singular : plural;
const value = getValueFromCatalog(singular, django.pluralidx(count));
if (value !== undefined) {
return value;
} else {
return value.constructor === Array ? value[django.pluralidx(count)] : value;
return (count == 1) ? singular : plural;
}
};

View File

@ -25,4 +25,4 @@ Indices, glossary and tables
* :ref:`genindex`
* :ref:`modindex`
* :doc:`glossary`
* :doc:`/glossary`

View File

@ -120,7 +120,7 @@ this::
# ...
The option (``delete`` in our example) is available in the options dict
parameter of the handle method. See the :py:mod:`argparse` Python documentation
parameter of the handle method. See the :mod:`argparse` Python documentation
for more about ``add_argument`` usage.
In addition to being able to add custom command line options, all
@ -208,7 +208,7 @@ All attributes can be set in your derived class and can be used in
If your command defines mandatory positional arguments, you can customize
the message error returned in the case of missing arguments. The default is
output by :py:mod:`argparse` ("too few arguments").
output by :mod:`argparse` ("too few arguments").
.. attribute:: BaseCommand.output_transaction

View File

@ -29,8 +29,8 @@ You should also consider how you will handle :doc:`static files
:doc:`error reporting</howto/error-reporting>`.
Finally, before you deploy your application to production, you should run
through our :doc:`deployment checklist<checklist>` to ensure that your
configurations are suitable.
through our :doc:`deployment checklist </howto/deployment/checklist>` to ensure
that your configurations are suitable.
.. _WSGI: https://wsgi.readthedocs.io/en/latest/
.. _ASGI: https://asgi.readthedocs.io/en/latest/

View File

@ -25,7 +25,7 @@ To send a log message from within your code, you place a logging call into it.
logging, use a view function as suggested in the example below.
First, import the Python logging library, and then obtain a logger instance
with :py:func:`logging.getLogger`. Provide the ``getLogger()`` method with a
with :func:`logging.getLogger`. Provide the ``getLogger()`` method with a
name to identify it and the records it emits. A good option is to use
``__name__`` (see :ref:`naming-loggers` below for more on this) which will
provide the name of the current Python module as a dotted path::
@ -43,7 +43,7 @@ And then in a function, for example in a view, send a record to the logger::
if some_risky_state:
logger.warning("Platform is running at risk")
When this code is executed, a :py:class:`~logging.LogRecord` containing that
When this code is executed, a :class:`~logging.LogRecord` containing that
message will be sent to the logger. If you're using Django's default logging
configuration, the message will appear in the console.
@ -129,7 +129,7 @@ file ``general.log`` (at the project root):
Different handler classes take different configuration options. For more
information on available handler classes, see the
:class:`~django.utils.log.AdminEmailHandler` provided by Django and the various
:py:mod:`handler classes <logging.handlers>` provided by Python.
:mod:`handler classes <logging.handlers>` provided by Python.
Logging levels can also be set on the handlers (by default, they accept log
messages of all levels). Using the example above, adding:
@ -238,7 +238,7 @@ application. A named logging configuration will capture logs only from loggers
with matching names.
The namespace of a logger instance is defined using
:py:func:`~logging.getLogger`. For example in ``views.py`` of ``my_app``::
:func:`~logging.getLogger`. For example in ``views.py`` of ``my_app``::
logger = logging.getLogger(__name__)

View File

@ -12,34 +12,34 @@ First steps
Are you new to Django or to programming? This is the place to start!
* **From scratch:**
:doc:`Overview <intro/overview>` |
:doc:`Installation <intro/install>`
:doc:`Overview </intro/overview>` |
:doc:`Installation </intro/install>`
* **Tutorial:**
:doc:`Part 1: Requests and responses <intro/tutorial01>` |
:doc:`Part 2: Models and the admin site <intro/tutorial02>` |
:doc:`Part 3: Views and templates <intro/tutorial03>` |
:doc:`Part 4: Forms and generic views <intro/tutorial04>` |
:doc:`Part 5: Testing <intro/tutorial05>` |
:doc:`Part 6: Static files <intro/tutorial06>` |
:doc:`Part 7: Customizing the admin site <intro/tutorial07>` |
:doc:`Part 8: Adding third-party packages <intro/tutorial08>`
:doc:`Part 1: Requests and responses </intro/tutorial01>` |
:doc:`Part 2: Models and the admin site </intro/tutorial02>` |
:doc:`Part 3: Views and templates </intro/tutorial03>` |
:doc:`Part 4: Forms and generic views </intro/tutorial04>` |
:doc:`Part 5: Testing </intro/tutorial05>` |
:doc:`Part 6: Static files </intro/tutorial06>` |
:doc:`Part 7: Customizing the admin site </intro/tutorial07>` |
:doc:`Part 8: Adding third-party packages </intro/tutorial08>`
* **Advanced Tutorials:**
:doc:`How to write reusable apps <intro/reusable-apps>` |
:doc:`Writing your first contribution to Django <intro/contributing>`
:doc:`How to write reusable apps </intro/reusable-apps>` |
:doc:`Writing your first contribution to Django </intro/contributing>`
Getting help
============
Having trouble? We'd like to help!
* Try the :doc:`FAQ <faq/index>` -- it's got answers to many common questions.
* Try the :doc:`FAQ </faq/index>` -- it's got answers to many common questions.
* Looking for specific information? Try the :ref:`genindex`, :ref:`modindex` or
the :doc:`detailed table of contents <contents>`.
the :doc:`detailed table of contents </contents>`.
* Not found anything? See :doc:`faq/help` for information on getting support
* Not found anything? See :doc:`/faq/help` for information on getting support
and asking questions to the community.
* Report bugs with Django in our `ticket tracker`_.
@ -74,46 +74,46 @@ Django provides an abstraction layer (the "models") for structuring and
manipulating the data of your web application. Learn more about it below:
* **Models:**
:doc:`Introduction to models <topics/db/models>` |
:doc:`Field types <ref/models/fields>` |
:doc:`Indexes <ref/models/indexes>` |
:doc:`Meta options <ref/models/options>` |
:doc:`Model class <ref/models/class>`
:doc:`Introduction to models </topics/db/models>` |
:doc:`Field types </ref/models/fields>` |
:doc:`Indexes </ref/models/indexes>` |
:doc:`Meta options </ref/models/options>` |
:doc:`Model class </ref/models/class>`
* **QuerySets:**
:doc:`Making queries <topics/db/queries>` |
:doc:`QuerySet method reference <ref/models/querysets>` |
:doc:`Lookup expressions <ref/models/lookups>`
:doc:`Making queries </topics/db/queries>` |
:doc:`QuerySet method reference </ref/models/querysets>` |
:doc:`Lookup expressions </ref/models/lookups>`
* **Model instances:**
:doc:`Instance methods <ref/models/instances>` |
:doc:`Accessing related objects <ref/models/relations>`
:doc:`Instance methods </ref/models/instances>` |
:doc:`Accessing related objects </ref/models/relations>`
* **Migrations:**
:doc:`Introduction to Migrations<topics/migrations>` |
:doc:`Operations reference <ref/migration-operations>` |
:doc:`SchemaEditor <ref/schema-editor>` |
:doc:`Writing migrations <howto/writing-migrations>`
:doc:`Introduction to Migrations</topics/migrations>` |
:doc:`Operations reference </ref/migration-operations>` |
:doc:`SchemaEditor </ref/schema-editor>` |
:doc:`Writing migrations </howto/writing-migrations>`
* **Advanced:**
:doc:`Managers <topics/db/managers>` |
:doc:`Raw SQL <topics/db/sql>` |
:doc:`Transactions <topics/db/transactions>` |
:doc:`Aggregation <topics/db/aggregation>` |
:doc:`Search <topics/db/search>` |
:doc:`Custom fields <howto/custom-model-fields>` |
:doc:`Multiple databases <topics/db/multi-db>` |
:doc:`Custom lookups <howto/custom-lookups>` |
:doc:`Query Expressions <ref/models/expressions>` |
:doc:`Conditional Expressions <ref/models/conditional-expressions>` |
:doc:`Database Functions <ref/models/database-functions>`
:doc:`Managers </topics/db/managers>` |
:doc:`Raw SQL </topics/db/sql>` |
:doc:`Transactions </topics/db/transactions>` |
:doc:`Aggregation </topics/db/aggregation>` |
:doc:`Search </topics/db/search>` |
:doc:`Custom fields </howto/custom-model-fields>` |
:doc:`Multiple databases </topics/db/multi-db>` |
:doc:`Custom lookups </howto/custom-lookups>` |
:doc:`Query Expressions </ref/models/expressions>` |
:doc:`Conditional Expressions </ref/models/conditional-expressions>` |
:doc:`Database Functions </ref/models/database-functions>`
* **Other:**
:doc:`Supported databases <ref/databases>` |
:doc:`Legacy databases <howto/legacy-databases>` |
:doc:`Providing initial data <howto/initial-data>` |
:doc:`Optimize database access <topics/db/optimization>` |
:doc:`PostgreSQL specific features <ref/contrib/postgres/index>`
:doc:`Supported databases </ref/databases>` |
:doc:`Legacy databases </howto/legacy-databases>` |
:doc:`Providing initial data </howto/initial-data>` |
:doc:`Optimize database access </topics/db/optimization>` |
:doc:`PostgreSQL specific features </ref/contrib/postgres/index>`
The view layer
==============
@ -123,39 +123,39 @@ processing a user's request and for returning the response. Find all you need
to know about views via the links below:
* **The basics:**
:doc:`URLconfs <topics/http/urls>` |
:doc:`View functions <topics/http/views>` |
:doc:`Shortcuts <topics/http/shortcuts>` |
:doc:`Decorators <topics/http/decorators>` |
:doc:`Asynchronous Support <topics/async>`
:doc:`URLconfs </topics/http/urls>` |
:doc:`View functions </topics/http/views>` |
:doc:`Shortcuts </topics/http/shortcuts>` |
:doc:`Decorators </topics/http/decorators>` |
:doc:`Asynchronous Support </topics/async>`
* **Reference:**
:doc:`Built-in Views <ref/views>` |
:doc:`Request/response objects <ref/request-response>` |
:doc:`TemplateResponse objects <ref/template-response>`
:doc:`Built-in Views </ref/views>` |
:doc:`Request/response objects </ref/request-response>` |
:doc:`TemplateResponse objects </ref/template-response>`
* **File uploads:**
:doc:`Overview <topics/http/file-uploads>` |
:doc:`File objects <ref/files/file>` |
:doc:`Storage API <ref/files/storage>` |
:doc:`Managing files <topics/files>` |
:doc:`Custom storage <howto/custom-file-storage>`
:doc:`Overview </topics/http/file-uploads>` |
:doc:`File objects </ref/files/file>` |
:doc:`Storage API </ref/files/storage>` |
:doc:`Managing files </topics/files>` |
:doc:`Custom storage </howto/custom-file-storage>`
* **Class-based views:**
:doc:`Overview <topics/class-based-views/index>` |
:doc:`Built-in display views <topics/class-based-views/generic-display>` |
:doc:`Built-in editing views <topics/class-based-views/generic-editing>` |
:doc:`Using mixins <topics/class-based-views/mixins>` |
:doc:`API reference <ref/class-based-views/index>` |
:doc:`Flattened index<ref/class-based-views/flattened-index>`
:doc:`Overview </topics/class-based-views/index>` |
:doc:`Built-in display views </topics/class-based-views/generic-display>` |
:doc:`Built-in editing views </topics/class-based-views/generic-editing>` |
:doc:`Using mixins </topics/class-based-views/mixins>` |
:doc:`API reference </ref/class-based-views/index>` |
:doc:`Flattened index </ref/class-based-views/flattened-index>`
* **Advanced:**
:doc:`Generating CSV <howto/outputting-csv>` |
:doc:`Generating PDF <howto/outputting-pdf>`
:doc:`Generating CSV </howto/outputting-csv>` |
:doc:`Generating PDF </howto/outputting-pdf>`
* **Middleware:**
:doc:`Overview <topics/http/middleware>` |
:doc:`Built-in middleware classes <ref/middleware>`
:doc:`Overview </topics/http/middleware>` |
:doc:`Built-in middleware classes </ref/middleware>`
The template layer
==================
@ -165,17 +165,17 @@ information to be presented to the user. Learn how this syntax can be used by
designers and how it can be extended by programmers:
* **The basics:**
:doc:`Overview <topics/templates>`
:doc:`Overview </topics/templates>`
* **For designers:**
:doc:`Language overview <ref/templates/language>` |
:doc:`Built-in tags and filters <ref/templates/builtins>` |
:doc:`Humanization <ref/contrib/humanize>`
:doc:`Language overview </ref/templates/language>` |
:doc:`Built-in tags and filters </ref/templates/builtins>` |
:doc:`Humanization </ref/contrib/humanize>`
* **For programmers:**
:doc:`Template API <ref/templates/api>` |
:doc:`Custom tags and filters <howto/custom-template-tags>` |
:doc:`Custom template backend <howto/custom-template-backend>`
:doc:`Template API </ref/templates/api>` |
:doc:`Custom tags and filters </howto/custom-template-tags>` |
:doc:`Custom template backend </howto/custom-template-backend>`
Forms
=====
@ -184,16 +184,16 @@ Django provides a rich framework to facilitate the creation of forms and the
manipulation of form data.
* **The basics:**
:doc:`Overview <topics/forms/index>` |
:doc:`Form API <ref/forms/api>` |
:doc:`Built-in fields <ref/forms/fields>` |
:doc:`Built-in widgets <ref/forms/widgets>`
:doc:`Overview </topics/forms/index>` |
:doc:`Form API </ref/forms/api>` |
:doc:`Built-in fields </ref/forms/fields>` |
:doc:`Built-in widgets </ref/forms/widgets>`
* **Advanced:**
:doc:`Forms for models <topics/forms/modelforms>` |
:doc:`Integrating media <topics/forms/media>` |
:doc:`Formsets <topics/forms/formsets>` |
:doc:`Customizing validation <ref/forms/validation>`
:doc:`Forms for models </topics/forms/modelforms>` |
:doc:`Integrating media </topics/forms/media>` |
:doc:`Formsets </topics/forms/formsets>` |
:doc:`Customizing validation </ref/forms/validation>`
The development process
=======================
@ -202,32 +202,32 @@ Learn about the various components and tools to help you in the development and
testing of Django applications:
* **Settings:**
:doc:`Overview <topics/settings>` |
:doc:`Full list of settings <ref/settings>`
:doc:`Overview </topics/settings>` |
:doc:`Full list of settings </ref/settings>`
* **Applications:**
:doc:`Overview <ref/applications>`
:doc:`Overview </ref/applications>`
* **Exceptions:**
:doc:`Overview <ref/exceptions>`
:doc:`Overview </ref/exceptions>`
* **django-admin and manage.py:**
:doc:`Overview <ref/django-admin>` |
:doc:`Adding custom commands <howto/custom-management-commands>`
:doc:`Overview </ref/django-admin>` |
:doc:`Adding custom commands </howto/custom-management-commands>`
* **Testing:**
:doc:`Introduction <topics/testing/index>` |
:doc:`Writing and running tests <topics/testing/overview>` |
:doc:`Included testing tools <topics/testing/tools>` |
:doc:`Advanced topics <topics/testing/advanced>`
:doc:`Introduction </topics/testing/index>` |
:doc:`Writing and running tests </topics/testing/overview>` |
:doc:`Included testing tools </topics/testing/tools>` |
:doc:`Advanced topics </topics/testing/advanced>`
* **Deployment:**
:doc:`Overview <howto/deployment/index>` |
:doc:`WSGI servers <howto/deployment/wsgi/index>` |
:doc:`ASGI servers <howto/deployment/asgi/index>` |
:doc:`Deploying static files <howto/static-files/deployment>` |
:doc:`Tracking code errors by email <howto/error-reporting>` |
:doc:`Deployment checklist <howto/deployment/checklist>`
:doc:`Overview </howto/deployment/index>` |
:doc:`WSGI servers </howto/deployment/wsgi/index>` |
:doc:`ASGI servers </howto/deployment/asgi/index>` |
:doc:`Deploying static files </howto/static-files/deployment>` |
:doc:`Tracking code errors by email </howto/error-reporting>` |
:doc:`Deployment checklist </howto/deployment/checklist>`
The admin
=========
@ -235,9 +235,9 @@ The admin
Find all you need to know about the automated admin interface, one of Django's
most popular features:
* :doc:`Admin site <ref/contrib/admin/index>`
* :doc:`Admin actions <ref/contrib/admin/actions>`
* :doc:`Admin documentation generator<ref/contrib/admin/admindocs>`
* :doc:`Admin site </ref/contrib/admin/index>`
* :doc:`Admin actions </ref/contrib/admin/actions>`
* :doc:`Admin documentation generator </ref/contrib/admin/admindocs>`
Security
========
@ -245,13 +245,13 @@ Security
Security is a topic of paramount importance in the development of web
applications and Django provides multiple protection tools and mechanisms:
* :doc:`Security overview <topics/security>`
* :doc:`Disclosed security issues in Django <releases/security>`
* :doc:`Clickjacking protection <ref/clickjacking>`
* :doc:`Cross Site Request Forgery protection <ref/csrf>`
* :doc:`Cryptographic signing <topics/signing>`
* :doc:`Security overview </topics/security>`
* :doc:`Disclosed security issues in Django </releases/security>`
* :doc:`Clickjacking protection </ref/clickjacking>`
* :doc:`Cross Site Request Forgery protection </ref/csrf>`
* :doc:`Cryptographic signing </topics/signing>`
* :ref:`Security Middleware <security-middleware>`
* :doc:`Content Security Policy <ref/csp>`
* :doc:`Content Security Policy </ref/csp>`
Internationalization and localization
=====================================
@ -260,10 +260,10 @@ Django offers a robust internationalization and localization framework to
assist you in the development of applications for multiple languages and world
regions:
* :doc:`Overview <topics/i18n/index>` |
:doc:`Internationalization <topics/i18n/translation>` |
* :doc:`Overview </topics/i18n/index>` |
:doc:`Internationalization </topics/i18n/translation>` |
:ref:`Localization <how-to-create-language-files>` |
:doc:`Localized web UI formatting and form input <topics/i18n/formatting>`
:doc:`Localized web UI formatting and form input </topics/i18n/formatting>`
* :doc:`Time zones </topics/i18n/timezones>`
Performance and optimization
@ -272,14 +272,14 @@ Performance and optimization
There are a variety of techniques and tools that can help get your code running
more efficiently - faster, and using fewer system resources.
* :doc:`Performance and optimization overview <topics/performance>`
* :doc:`Performance and optimization overview </topics/performance>`
Geographic framework
====================
:doc:`GeoDjango <ref/contrib/gis/index>` intends to be a world-class geographic
web framework. Its goal is to make it as easy as possible to build GIS web
applications and harness the power of spatially enabled data.
:doc:`GeoDjango </ref/contrib/gis/index>` intends to be a world-class
geographic web framework. Its goal is to make it as easy as possible to build
GIS web applications and harness the power of spatially enabled data.
Common web application tools
============================
@ -288,36 +288,36 @@ Django offers multiple tools commonly needed in the development of web
applications:
* **Authentication:**
:doc:`Overview <topics/auth/index>` |
:doc:`Using the authentication system <topics/auth/default>` |
:doc:`Password management <topics/auth/passwords>` |
:doc:`Customizing authentication <topics/auth/customizing>` |
:doc:`API Reference <ref/contrib/auth>`
* :doc:`Caching <topics/cache>`
* :doc:`Logging <topics/logging>`
* :doc:`Sending emails <topics/email>`
* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>`
* :doc:`Pagination <topics/pagination>`
* :doc:`Messages framework <ref/contrib/messages>`
* :doc:`Serialization <topics/serialization>`
* :doc:`Sessions <topics/http/sessions>`
* :doc:`Sitemaps <ref/contrib/sitemaps>`
* :doc:`Static files management <ref/contrib/staticfiles>`
* :doc:`Data validation <ref/validators>`
:doc:`Overview </topics/auth/index>` |
:doc:`Using the authentication system </topics/auth/default>` |
:doc:`Password management </topics/auth/passwords>` |
:doc:`Customizing authentication </topics/auth/customizing>` |
:doc:`API Reference </ref/contrib/auth>`
* :doc:`Caching </topics/cache>`
* :doc:`Logging </topics/logging>`
* :doc:`Sending emails </topics/email>`
* :doc:`Syndication feeds (RSS/Atom) </ref/contrib/syndication>`
* :doc:`Pagination </topics/pagination>`
* :doc:`Messages framework </ref/contrib/messages>`
* :doc:`Serialization </topics/serialization>`
* :doc:`Sessions </topics/http/sessions>`
* :doc:`Sitemaps </ref/contrib/sitemaps>`
* :doc:`Static files management </ref/contrib/staticfiles>`
* :doc:`Data validation </ref/validators>`
Other core functionalities
==========================
Learn about some other core functionalities of the Django framework:
* :doc:`Conditional content processing <topics/conditional-view-processing>`
* :doc:`Content types and generic relations <ref/contrib/contenttypes>`
* :doc:`Flatpages <ref/contrib/flatpages>`
* :doc:`Redirects <ref/contrib/redirects>`
* :doc:`Signals <topics/signals>`
* :doc:`System check framework <topics/checks>`
* :doc:`The sites framework <ref/contrib/sites>`
* :doc:`Unicode in Django <ref/unicode>`
* :doc:`Conditional content processing </topics/conditional-view-processing>`
* :doc:`Content types and generic relations </ref/contrib/contenttypes>`
* :doc:`Flatpages </ref/contrib/flatpages>`
* :doc:`Redirects </ref/contrib/redirects>`
* :doc:`Signals </topics/signals>`
* :doc:`System check framework </topics/checks>`
* :doc:`The sites framework </ref/contrib/sites>`
* :doc:`Unicode in Django </ref/unicode>`
The Django open-source project
==============================
@ -326,23 +326,23 @@ Learn about the development process for the Django project itself and about how
you can contribute:
* **Community:**
:doc:`Contributing to Django <internals/contributing/index>` |
:doc:`The release process <internals/release-process>` |
:doc:`Team organization <internals/organization>` |
:doc:`The Django source code repository <internals/git>` |
:doc:`Security policies <internals/security>` |
:doc:`Mailing lists and Forum<internals/mailing-lists>`
:doc:`Contributing to Django </internals/contributing/index>` |
:doc:`The release process </internals/release-process>` |
:doc:`Team organization </internals/organization>` |
:doc:`The Django source code repository </internals/git>` |
:doc:`Security policies </internals/security>` |
:doc:`Mailing lists and Forum </internals/mailing-lists>`
* **Design philosophies:**
:doc:`Overview <misc/design-philosophies>`
:doc:`Overview </misc/design-philosophies>`
* **Documentation:**
:doc:`About this documentation <internals/contributing/writing-documentation>`
:doc:`About this documentation </internals/contributing/writing-documentation>`
* **Third-party distributions:**
:doc:`Overview <misc/distributions>`
:doc:`Overview </misc/distributions>`
* **Django over time:**
:doc:`API stability <misc/api-stability>` |
:doc:`Release notes and upgrading instructions <releases/index>` |
:doc:`Deprecation Timeline <internals/deprecation>`
:doc:`API stability </misc/api-stability>` |
:doc:`Release notes and upgrading instructions </releases/index>` |
:doc:`Deprecation Timeline </internals/deprecation>`

View File

@ -55,7 +55,7 @@ particular:
as they are filed.
To understand the lifecycle of your ticket once you have created it, refer to
:doc:`triaging-tickets`.
:ref:`triage-workflow`.
Reporting user interface bugs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -4,8 +4,8 @@ Committing code
This section is addressed to the mergers and to anyone interested in knowing
how code gets committed into Django. If you're a community member who wants to
contribute code to Django, look at :doc:`writing-code/working-with-git`
instead.
contribute code to Django, look at
:doc:`/internals/contributing/writing-code/working-with-git` instead.
.. _handling-pull-requests:

View File

@ -61,8 +61,8 @@ the date, time and numbers formatting particularities of your locale. See
The format files aren't managed by the use of Transifex. To change them, you
must:
* :doc:`Create a pull request<writing-code/submitting-patches>` against the
Django Git ``main`` branch, as for any code change.
* :ref:`Create a pull request <patch-review-checklist>` against the Django Git
``main`` branch, as for any code change.
* Open a ticket in Django's ticket system, set its ``Component`` field to
``Translations``, set the "has patch" flag, and include the link to the pull

View File

@ -47,14 +47,15 @@ Keep old patches up-to-date
Oftentimes the codebase will change between a patch being submitted and the
time it gets reviewed. Make sure it still applies cleanly and functions as
expected. Updating a patch is both useful and important! See more on
:doc:`writing-code/submitting-patches`.
:ref:`patch-review-checklist`.
Write some documentation
------------------------
Django's documentation is great but it can always be improved. Did you find a
typo? Do you think that something should be clarified? Go ahead and suggest a
documentation patch! See also the guide on :doc:`writing-documentation`.
documentation patch! See also the guide on
:doc:`/internals/contributing/writing-documentation`.
.. note::

View File

@ -29,11 +29,13 @@ confusion or disagreement.
Django is a community project, and every contribution helps. We can't do this
without **you**!
.. _triage-workflow:
Triage workflow
===============
Unfortunately, not all reports in the ticket tracker provide all the
:doc:`required details<bugs-and-features>`. A number of tickets have proposed
:ref:`required details <reporting-bugs>`. A number of tickets have proposed
solutions, but those don't necessarily meet all the requirements :ref:`adhering
to the guidelines for contributing <patch-style>`.
@ -168,8 +170,8 @@ Has patch
---------
This means the ticket has an associated solution. These will be reviewed to
ensure they adhere to the :doc:`documented guidelines
<writing-code/submitting-patches>`.
ensure they adhere to the :ref:`documented guidelines
<patch-review-checklist>`.
The following three fields (Needs documentation, Needs tests,
Patch needs improvement) apply only if a patch has been supplied.
@ -234,8 +236,11 @@ majority of tickets have a severity of "Normal".
Version
-------
It is possible to use the *version* attribute to indicate in which
version the reported bug was identified.
The *version* attribute indicates the earliest version in which the bug was
reproduced. During triage, this field can be updated, but there is no need to
make further updates when that version goes out of support. The field should
not be reset to "dev" to show the issue still exists: instead, the tested
commit hash can be noted in a comment.
UI/UX
-----
@ -350,8 +355,7 @@ Then, you can help out by:
"wontfix".
* Closing "Unreviewed" tickets as "needsinfo" when the description is too
sparse to be actionable, or when they're feature requests requiring a
discussion on the `Django Forum`_.
sparse to be actionable.
* Correcting the "Needs tests", "Needs documentation", or "Has patch"
flags for tickets where they are incorrectly set.
@ -383,7 +387,7 @@ Then, you can help out by:
several that are useful for triaging tickets and reviewing proposals as
suggested above.
You can also find more :doc:`new-contributors`.
You can also find more :doc:`/internals/contributing/new-contributors`.
.. _Reports page: https://code.djangoproject.com/wiki/Reports

View File

@ -56,8 +56,8 @@ Python style
These limits are checked when ``flake8`` is run.
* String variable interpolation may use
:py:ref:`%-formatting <old-string-formatting>`, :py:ref:`f-strings
<f-strings>`, or :py:meth:`str.format` as appropriate, with the goal of
:ref:`%-formatting <old-string-formatting>`, :ref:`f-strings
<f-strings>`, or :meth:`str.format` as appropriate, with the goal of
maximizing code readability.
Final judgments of readability are left to the Merger's discretion. As a
@ -504,6 +504,6 @@ JavaScript style
================
For details about the JavaScript code style used by Django, see
:doc:`javascript`.
:doc:`/internals/contributing/writing-code/javascript`.
.. _editorconfig: https://editorconfig.org/

View File

@ -15,7 +15,8 @@ If you are fixing a really trivial issue, for example changing a word in the
documentation, the preferred way to provide the patch is using GitHub pull
requests without a Trac ticket.
See the :doc:`working-with-git` for more details on how to use pull requests.
See the :doc:`/internals/contributing/writing-code/working-with-git` for more
details on how to use pull requests.
"Claiming" tickets
==================
@ -109,19 +110,20 @@ requirements:
* The code required to fix a problem or add a feature is an essential part
of a solution, but it is not the only part. A good fix should also include a
:doc:`regression test <unit-tests>` to validate the behavior that has been
fixed and to prevent the problem from arising again. Also, if some tickets
are relevant to the code that you've written, mention the ticket numbers in
some comments in the test so that one can easily trace back the relevant
discussions after your patch gets committed, and the tickets get closed.
:doc:`regression test </internals/contributing/writing-code/unit-tests>` to
validate the behavior that has been fixed and to prevent the problem from
arising again. Also, if some tickets are relevant to the code that you've
written, mention the ticket numbers in some comments in the test so that one
can easily trace back the relevant discussions after your patch gets
committed, and the tickets get closed.
* If the code adds a new feature, or modifies the behavior of an existing
feature, the change should also contain documentation.
When you think your work is ready to be reviewed, send :doc:`a GitHub pull
request <working-with-git>`.
If you can't send a pull request for some reason, you can also use patches in
Trac. When using this style, follow these guidelines.
request </internals/contributing/writing-code/working-with-git>`. If you can't
send a pull request for some reason, you can also use patches in Trac. When
using this style, follow these guidelines.
* Submit patches in the format returned by the ``git diff`` command.

View File

@ -4,7 +4,7 @@ Working with Git and GitHub
This section explains how the community can contribute code to Django via pull
requests. If you're interested in how :ref:`mergers <mergers-team>` handle
them, see :doc:`../committing-code`.
them, see :ref:`handling-pull-requests`.
Below, we are going to show how to create a GitHub pull request containing the
changes for Trac ticket #xxxxx. By creating a fully-ready pull request, you
@ -142,7 +142,7 @@ When you think your work is ready to be pulled into Django, you should create
a pull request at GitHub. A good pull request means:
* commits with one logical change in each, following the
:doc:`coding style <coding-style>`,
:doc:`coding style </internals/contributing/writing-code/coding-style>`,
* well-formed messages for each commit: a summary line and then paragraphs
wrapped at 72 characters thereafter -- see the :ref:`committing guidelines

View File

@ -53,8 +53,6 @@ details on these changes.
* The ``django.core.mail.forbid_multi_line_headers()`` and
``django.core.mail.message.sanitize_address()`` functions will be removed.
* The ``django.utils.crypto.constant_time_compare()`` function will be removed.
.. _deprecation-removed-in-6.1:
6.1
@ -744,8 +742,8 @@ details on these changes.
* The ability to use a dotted Python path for the ``LOGIN_URL`` and
``LOGIN_REDIRECT_URL`` settings will be removed.
* Support for :py:mod:`optparse` will be dropped for custom management commands
(replaced by :py:mod:`argparse`).
* Support for :mod:`optparse` will be dropped for custom management commands
(replaced by :mod:`argparse`).
* The class ``django.core.management.NoArgsCommand`` will be removed. Use
:class:`~django.core.management.BaseCommand` instead, which takes no

View File

@ -31,7 +31,8 @@ own branch, called ``stable/A.B.x``, and bugfix/security releases will be
issued from those branches.
For more information about how the Django project issues new releases for
security purposes, please see :doc:`our security policies <security>`.
security purposes, please see :doc:`our security policies
</internals/security>`.
.. glossary::

View File

@ -5,14 +5,16 @@ from os.path import abspath, dirname, splitext
from unittest import mock
from sphinxlint.checkers import (
_ROLE_BODY,
_is_long_interpreted_text,
_is_very_long_string_literal,
_starts_with_anonymous_hyperlink,
_starts_with_directive_or_hyperlink,
)
from sphinxlint.checkers import checker as sphinxlint_checker
from sphinxlint.rst import SIMPLENAME
from sphinxlint.sphinxlint import check_text
from sphinxlint.utils import PER_FILE_CACHES, hide_non_rst_blocks
from sphinxlint.utils import PER_FILE_CACHES, hide_non_rst_blocks, paragraphs
def django_check_file(filename, checkers, options=None):
@ -94,7 +96,7 @@ def check_line_too_long_django(file, lines, options=None):
continue
except IndexError:
# End of file
continue
pass
if len(set(line.strip())) == 1 and len(line) == len(lines[lno - 1]):
continue # Ignore heading underline
if lno in table_rows:
@ -116,6 +118,40 @@ def check_line_too_long_django(file, lines, options=None):
yield lno + 1, f"Line too long ({len(line) - 1}/{options.max_line_length})"
_PYTHON_DOMAIN = re.compile(f":py:{SIMPLENAME}:`{_ROLE_BODY}`")
@sphinxlint_checker(".rst", enabled=False, rst_only=True)
def check_python_domain_in_roles(file, lines, options=None):
"""
:py: indicates the Python language domain. This means code writen in
Python, not Python built-ins in particular.
Bad: :py:class:`email.message.EmailMessage`
Good: :class:`email.message.EmailMessage`
"""
for lno, line in enumerate(lines, start=1):
role = _PYTHON_DOMAIN.search(line)
if role:
yield lno, f":py domain is the default and can be omitted {role.group(0)!r}"
_DOC_CAPTURE_TARGET_RE = re.compile(r":doc:`(?:[^<`]+<)?([^>`]+)>?`")
@sphinxlint_checker(".rst", rst_only=True)
def check_absolute_targets_doc_role(file, lines, options=None):
for paragraph_lno, paragraph in paragraphs(lines):
for error in _DOC_CAPTURE_TARGET_RE.finditer(paragraph):
target = error.group(1)
# Skip absolute or intersphinx refs like "python:using/windows".
if target.startswith("/") or ":" in target.split("/", 1)[0]:
continue
# Relative target, report as a violation.
error_offset = paragraph[: error.start()].count("\n")
yield (paragraph_lno + error_offset, target)
import sphinxlint # noqa: E402
sphinxlint.check_file = django_check_file

View File

@ -1436,7 +1436,7 @@ default templates used by the :class:`ModelAdmin` views:
The ``delete_queryset()`` method is given the ``HttpRequest`` and a
``QuerySet`` of objects to be deleted. Override this method to customize
the deletion process for the "delete selected objects" :doc:`action
<actions>`.
</ref/contrib/admin/actions>`.
.. method:: ModelAdmin.save_formset(request, form, formset, change)
@ -2055,7 +2055,7 @@ default templates used by the :class:`ModelAdmin` views:
.. method:: ModelAdmin.get_deleted_objects(objs, request)
A hook for customizing the deletion process of the :meth:`delete_view` and
the "delete selected" :doc:`action <actions>`.
the "delete selected" :doc:`action </ref/contrib/admin/actions>`.
The ``objs`` argument is a homogeneous iterable of objects (a ``QuerySet``
or a list of model instances) to be deleted, and ``request`` is the

View File

@ -156,7 +156,7 @@ Geometry Lookups
----------------
Geographic queries with geometries take the following general form (assuming
the ``Zipcode`` model used in the :doc:`model-api`):
the ``Zipcode`` model used in the :doc:`/ref/contrib/gis/model-api`):
.. code-block:: text
@ -192,7 +192,8 @@ used to pass a band index. On the right hand side, a tuple of the raster and
band index can be specified.
This results in the following general form for lookups involving rasters
(assuming the ``Elevation`` model used in the :doc:`model-api`):
(assuming the ``Elevation`` model used in the
:doc:`/ref/contrib/gis/model-api`):
.. code-block:: text
@ -234,11 +235,10 @@ Distance Queries
Introduction
------------
Distance calculations with spatial data is tricky because, unfortunately,
the Earth is not flat. Some distance queries with fields in a geographic
coordinate system may have to be expressed differently because of
limitations in PostGIS. Please see the :ref:`selecting-an-srid` section
in the :doc:`model-api` documentation for more details.
Distance calculations with spatial data is tricky because, unfortunately, the
Earth is not flat. Some distance queries with fields in a geographic coordinate
system may have to be expressed differently because of limitations in PostGIS.
Please see the :ref:`selecting-an-srid` section for more details.
.. _distance-lookups-intro:

View File

@ -85,7 +85,8 @@ queryset is calculated:
express the value in the units of your choice. For example,
``city.distance.mi`` is the distance value in miles and
``city.distance.km`` is the distance value in kilometers. See
:doc:`measure` for usage details and the list of :ref:`supported_units`.
:doc:`/ref/contrib/gis/measure` for usage details and the list of
:ref:`supported_units`.
``GeometryDistance``
--------------------

View File

@ -5,6 +5,11 @@ GDAL API
.. module:: django.contrib.gis.gdal
:synopsis: GeoDjango's high-level interface to the GDAL library.
.. _gdal-overview:
Overview
========
`GDAL`__ stands for **Geospatial Data Abstraction Library**,
and is a veritable "Swiss army knife" of GIS data functionality. A subset
of GDAL is the `OGR`__ Simple Features Library, which specializes
@ -24,9 +29,6 @@ to raster (image) data.
__ https://gdal.org/
__ https://gdal.org/user/vector_data_model.html
Overview
========
.. _gdal_sample_data:
Sample Data
@ -43,6 +45,8 @@ data sets that you can use for testing. You can download them here:
$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/cities/cities.{shp,prj,shx,dbf}
$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/rasters/raster.tif
.. _gdal_vector_data:
Vector Data Source Objects
==========================

View File

@ -5,6 +5,11 @@ Geolocation with GeoIP2
.. module:: django.contrib.gis.geoip2
:synopsis: Python interface for MaxMind's GeoIP2 databases.
.. _geoip2-overview:
Overview
========
The :class:`GeoIP2` object is a wrapper for the :pypi:`MaxMind geoip2 Python
library <geoip2>`. [#]_

View File

@ -5,6 +5,8 @@ GEOS API
.. module:: django.contrib.gis.geos
:synopsis: GeoDjango's high-level interface to the GEOS library.
.. _geos-overview:
Background
==========

View File

@ -2,19 +2,24 @@
Installing Geospatial libraries
===============================
.. _geolibs-list:
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.13, 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.11, 3.10, 3.9, 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.5, 3.4, 3.3, 3.2, 3.1
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 5.1, 5.0, 4.3
======================== ==================================== ================================ =======================================================
============================== ==================================== ================================ =======================================================
Program Description Required Supported Versions
============================== ==================================== ================================ =======================================================
:ref:`GEOS <geos-overview>` Geometry Engine Open Source Yes 3.14, 3.13, 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
:ref:`GDAL <gdal-overview>` Geospatial Data Abstraction Library Yes 3.11, 3.10, 3.9, 3.8, 3.7, 3.6, 3.5, 3.4, 3.3, 3.2, 3.1
:ref:`GeoIP <geoip2-overview>` IP-based geolocation library No 2
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.5, 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.
@ -27,6 +32,7 @@ totally fine with GeoDjango. Your mileage may vary.
GEOS 3.11.0 2022-07-01
GEOS 3.12.0 2023-06-27
GEOS 3.13.0 2024-09-06
GEOS 3.14.0 2025-08-21
GDAL 3.1.0 2020-05-07
GDAL 3.2.0 2020-11-02
GDAL 3.3.0 2021-05-03
@ -234,7 +240,7 @@ GDAL
`GDAL`__ is an excellent open source geospatial library that has support for
reading most vector and raster spatial data formats. Currently, GeoDjango only
supports :doc:`GDAL's vector data <../gdal>` capabilities [#]_.
supports :ref:`GDAL's vector data <gdal_vector_data>` capabilities [#]_.
:ref:`geosbuild` and :ref:`proj4` should be installed prior to building GDAL.
First download the latest GDAL release version and untar the archive:

View File

@ -8,7 +8,7 @@ In general, GeoDjango installation requires:
#. :ref:`Python and Django <django>`
#. :ref:`spatial_database`
#. :doc:`geolibs`
#. :ref:`geolibs-list`
Details for each of the requirements and installation instructions
are provided in the sections below. In addition, platform-specific

View File

@ -22,9 +22,9 @@ familiarize yourself with Django first.
.. note::
GeoDjango has additional requirements beyond what Django requires --
please consult the :doc:`installation documentation <install/index>`
for more details.
GeoDjango has additional requirements beyond what Django requires -- please
consult the :doc:`installation documentation
</ref/contrib/gis/install/index>` for more details.
This tutorial will guide you through the creation of a geographic web
application for viewing the `world borders`_. [#]_ Some of the code
@ -49,8 +49,8 @@ Create a Spatial Database
Typically no special setup is required, so you can create a database as you
would for any other project. We provide some tips for selected databases:
* :doc:`install/postgis`
* :doc:`install/spatialite`
* :doc:`/ref/contrib/gis/install/postgis`
* :doc:`/ref/contrib/gis/install/spatialite`
Create a New Project
--------------------
@ -305,7 +305,7 @@ Importing Spatial Data
======================
This section will show you how to import the world borders shapefile into the
database via GeoDjango models using the :doc:`layermapping`.
database via GeoDjango models using the :doc:`/ref/contrib/gis/layermapping`.
There are many different ways to import data into a spatial database --
besides the tools included within GeoDjango, you may also use the following:
@ -531,11 +531,13 @@ Next, import the ``load`` module, call the ``run`` routine, and watch
Try ``ogrinspect``
------------------
Now that you've seen how to define geographic models and import data with the
:doc:`layermapping`, it's possible to further automate this process with
use of the :djadmin:`ogrinspect` management command. The :djadmin:`ogrinspect`
command introspects a GDAL-supported vector data source (e.g., a shapefile)
and generates a model definition and ``LayerMapping`` dictionary automatically.
:doc:`/ref/contrib/gis/layermapping`, it's possible to further automate this
process with use of the :djadmin:`ogrinspect` management command. The
:djadmin:`ogrinspect` command introspects a GDAL-supported vector data source
(e.g., a shapefile) and generates a model definition and ``LayerMapping``
dictionary automatically.
The general usage of the command goes as follows:
@ -637,10 +639,10 @@ a ``contains`` lookup using the ``pnt_wkt`` as the parameter:
Here, you retrieved a ``QuerySet`` with only one model: the border of the
United States (exactly what you would expect).
Similarly, you may also use a :doc:`GEOS geometry object <geos>`.
Here, you can combine the ``intersects`` spatial lookup with the ``get``
method to retrieve only the ``WorldBorder`` instance for San Marino instead
of a queryset:
Similarly, you may also use a :doc:`GEOS geometry object
</ref/contrib/gis/geos>`. Here, you can combine the ``intersects`` spatial
lookup with the ``get`` method to retrieve only the ``WorldBorder`` instance
for San Marino instead of a queryset:
.. code-block:: pycon
@ -649,8 +651,8 @@ of a queryset:
>>> WorldBorder.objects.get(mpoly__intersects=pnt)
<WorldBorder: San Marino>
The ``contains`` and ``intersects`` lookups are just a subset of the
available queries -- the :doc:`db-api` documentation has more.
The ``contains`` and ``intersects`` lookups are just a subset of the available
queries -- the :doc:`/ref/contrib/gis/db-api` documentation has more.
.. _automatic-spatial-transformations:
@ -748,7 +750,7 @@ Geographic annotations
GeoDjango also offers a set of geographic annotations to compute distances and
several other operations (intersection, difference, etc.). See the
:doc:`functions` documentation.
:doc:`/ref/contrib/gis/functions` documentation.
Putting your data on the map
============================

View File

@ -492,7 +492,7 @@ This view function serves static files in development.
.. note::
To guess the served files' content types, this view relies on the
:py:mod:`mimetypes` module from the Python standard library, which itself
:mod:`mimetypes` module from the Python standard library, which itself
relies on the underlying platform's map files. If you find that this view
doesn't return proper content types for certain files, it is most likely
that the platform's map files are incorrect or need to be updated. This can

View File

@ -154,6 +154,92 @@ with the CSP specification.
secure, random nonce that is generated for each request. See detailed
explanation in :ref:`csp-nonce`.
Decorators
==========
.. module:: django.views.decorators.csp
Django provides decorators to control the Content Security Policy headers on a
per-view basis. These allow overriding or disabling the enforced or report-only
policy for specific views, providing fine-grained control when the global
settings are not sufficient. Applying these overrides fully replaces the base
CSP: they do not merge with existing rules. They can be used alongside the
constants defined in :class:`~django.utils.csp.CSP`.
.. warning::
Weakening or disabling a CSP policy on any page can compromise the security
of the entire site. Because of the "same origin" policy, an attacker could
exploit a vulnerability on one page to access other parts of the site.
.. function:: csp_override(config)(view)
Overrides the ``Content-Security-Policy`` header for the decorated view
using directives in the same format as the :setting:`SECURE_CSP` setting.
The ``config`` argument must be a mapping with the desired CSP directives.
If ``config`` is an empty mapping (``{}``), no CSP enforcement header will
be added to the response returned by that view, effectively disabling CSP
for that view.
Examples::
from django.http import HttpResponse
from django.utils.csp import CSP
from django.views.decorators.csp import csp_override
@csp_override(
{
"default-src": [CSP.SELF],
"img-src": [CSP.SELF, "data:"],
}
)
def my_view(request):
return HttpResponse("Custom Content-Security-Policy header applied")
@csp_override({})
def my_other_view(request):
return HttpResponse("No Content-Security-Policy header added")
.. function:: csp_report_only_override(config)(view)
Overrides the ``Content-Security-Policy-Report-Only`` header for the
decorated view using directives in the same format as the
:setting:`SECURE_CSP_REPORT_ONLY` setting.
Like :func:`csp_override`, the ``config`` argument must be a mapping with
the desired CSP directives. If ``config`` is an empty mapping (``{}``), no
CSP report-only header will be added to the response returned by that view,
effectively disabling report-only CSP for that view.
Examples::
from django.http import HttpResponse
from django.utils.csp import CSP
from django.views.decorators.csp import csp_report_only_override
@csp_report_only_override(
{
"default-src": [CSP.SELF],
"img-src": [CSP.SELF, "data:"],
"report-uri": "https://mysite.com/csp-report/",
}
)
def my_view(request):
return HttpResponse("Custom Content-Security-Policy-Report-Only header applied")
@csp_report_only_override({})
def my_other_view(request):
return HttpResponse("No Content-Security-Policy-Report-Only header added")
The examples above assume function-based views. For class-based views, see the
:ref:`guide for decorating class-based views <decorating-class-based-views>`.
.. _csp-nonce:
Nonce usage

View File

@ -951,7 +951,7 @@ Enabling JSON1 extension on SQLite
----------------------------------
To use :class:`~django.db.models.JSONField` on SQLite, you need to enable the
`JSON1 extension`_ on Python's :py:mod:`sqlite3` library. If the extension is
`JSON1 extension`_ on Python's :mod:`sqlite3` library. If the extension is
not enabled on your installation, a system error (``fields.E180``) will be
raised.

View File

@ -1845,7 +1845,7 @@ allows for the following options by default:
.. django-admin-option:: --pythonpath PYTHONPATH
Adds the given filesystem path to the Python :py:data:`sys.path` module
Adds the given filesystem path to the Python :data:`sys.path` module
attribute. If this isn't provided, ``django-admin`` will use the
:envvar:`PYTHONPATH` environment variable.

View File

@ -13,7 +13,7 @@ The ``File`` class
.. class:: File(file_object, name=None)
The :class:`File` class is a thin wrapper around a Python
:py:term:`file object` with some Django-specific additions.
:term:`file object` with some Django-specific additions.
Internally, Django uses this class when it needs to represent a file.
:class:`File` objects have the following attributes and methods:
@ -29,14 +29,14 @@ The ``File`` class
.. attribute:: file
The underlying :py:term:`file object` that this class wraps.
The underlying :term:`file object` that this class wraps.
.. admonition:: Be careful with this attribute in subclasses.
Some subclasses of :class:`File`, including
:class:`~django.core.files.base.ContentFile` and
:class:`~django.db.models.fields.files.FieldFile`, may replace this
attribute with an object other than a Python :py:term:`file
attribute with an object other than a Python :term:`file
object`. In these cases, this attribute may itself be a
:class:`File` subclass (and not necessarily the same subclass).
Whenever possible, use the attributes and methods of the subclass

View File

@ -942,8 +942,8 @@ Configuring the rendering of a form's widgets
.. attribute:: Form.default_renderer
Specifies the :doc:`renderer <renderers>` to use for the form. Defaults to
``None`` which means to use the default renderer specified by the
Specifies the :doc:`renderer </ref/forms/renderers>` to use for the form.
Defaults to ``None`` which means to use the default renderer specified by the
:setting:`FORM_RENDERER` setting.
You can set this as a class attribute when declaring your form or use the
@ -1070,9 +1070,9 @@ Customizing the error list format
.. attribute:: renderer
Specifies the :doc:`renderer <renderers>` to use for ``ErrorList``.
Defaults to ``None`` which means to use the default renderer
specified by the :setting:`FORM_RENDERER` setting.
Specifies the :doc:`renderer </ref/forms/renderers>` to use for
``ErrorList``. Defaults to ``None`` which means to use the default
renderer specified by the :setting:`FORM_RENDERER` setting.
.. attribute:: field_id

View File

@ -919,7 +919,7 @@ For each field, we describe the default widget used if you don't specify
.. attribute:: encoder
A :py:class:`json.JSONEncoder` subclass to serialize data types not
A :class:`json.JSONEncoder` subclass to serialize data types not
supported by the standard JSON serializer (e.g. ``datetime.datetime``
or :class:`~python:uuid.UUID`). For example, you can use the
:class:`~django.core.serializers.json.DjangoJSONEncoder` class.
@ -928,14 +928,14 @@ For each field, we describe the default widget used if you don't specify
.. attribute:: decoder
A :py:class:`json.JSONDecoder` subclass to deserialize the input. Your
A :class:`json.JSONDecoder` subclass to deserialize the input. Your
deserialization may need to account for the fact that you can't be
certain of the input type. For example, you run the risk of returning a
``datetime`` that was actually a string that just happened to be in the
same format chosen for ``datetime``\s.
The ``decoder`` can be used to validate the input. If
:py:class:`json.JSONDecodeError` is raised during the deserialization,
:class:`json.JSONDecodeError` is raised during the deserialization,
a ``ValidationError`` will be raised.
Defaults to ``json.JSONDecoder``.

View File

@ -1,15 +1,188 @@
====================
Model Form Functions
====================
Model Form API reference. For introductory material about model forms, see the
:doc:`/topics/forms/modelforms` topic guide.
===========
Model forms
===========
.. module:: django.forms.models
:synopsis: Django's functions for building model forms and formsets.
:synopsis: ModelForm API reference for inner ``Meta`` class and factory
functions
.. currentmodule:: django.forms
``ModelForm`` API reference. For introductory material about using a
``ModelForm``, see the :doc:`/topics/forms/modelforms` topic guide.
Model form ``Meta`` API
=======================
.. class:: ModelFormOptions
The ``_meta`` API is used to build forms that reflect a Django model. It is
accessible through the ``_meta`` attribute of each model form, and is an
``django.forms.models.ModelFormOptions`` instance.
The structure of the generated form can be customized by defining metadata
options as attributes of an inner ``Meta`` class. For example::
from django.forms import ModelForm
from myapp.models import Book
class BookForm(ModelForm):
class Meta:
model = Book
fields = ["title", "author"]
help_texts = {
"title": "The title of the book",
"author": "The author of the book",
}
# ... other attributes
Required attributes are :attr:`~ModelFormOptions.model`, and either
:attr:`~ModelFormOptions.fields` or :attr:`~ModelFormOptions.exclude`. All
other ``Meta`` attributes are optional.
Optional attributes, other than :attr:`~ModelFormOptions.localized_fields` and
:attr:`~ModelFormOptions.formfield_callback`, expect a dictionary that maps a
model field name to a value. Any field that is not defined in the dictionary
falls back to the field's default value.
.. admonition:: Invalid field names
Invalid or excluded field names in an optional dictionary attribute have no
effect, since fields that are not included are not accessed.
.. admonition:: Invalid Meta class attributes
You may define any attribute on a ``Meta`` class. Typos or incorrect
attribute names do not raise an error.
``error_messages``
------------------
.. attribute:: ModelFormOptions.error_messages
A dictionary that maps a model field name to a dictionary of error message
keys (``null``, ``blank``, ``invalid``, ``unique``, etc.) mapped to custom
error messages.
When a field is not specified, Django will fall back on the error messages
defined in that model field's :attr:`django.db.models.Field.error_messages`
and then finally on the default error messages for that field type.
``exclude``
-----------
.. attribute:: ModelFormOptions.exclude
A tuple or list of :attr:`~ModelFormOptions.model` field names to be
excluded from the form.
Either :attr:`~ModelFormOptions.fields` or
:attr:`~ModelFormOptions.exclude` must be set. If neither are set, an
:class:`~django.core.exceptions.ImproperlyConfigured` exception will be
raised. If :attr:`~ModelFormOptions.exclude` is set and
:attr:`~ModelFormOptions.fields` is unset, all model fields, except for
those specified in :attr:`~ModelFormOptions.exclude`, are included in the
form.
``field_classes``
-----------------
.. attribute:: ModelFormOptions.field_classes
A dictionary that maps a model field name to a :class:`~django.forms.Field`
class, which overrides the ``form_class`` used in the model field's
:meth:`.Field.formfield` method.
When a field is not specified, Django will fall back on the model field's
:ref:`default field class <model-form-field-types>`.
``fields``
----------
.. attribute:: ModelFormOptions.fields
A tuple or list of :attr:`~ModelFormOptions.model` field names to be
included in the form. The value ``'__all__'`` can be used to specify that
all fields should be included.
If any field is specified in :attr:`~ModelFormOptions.exclude`, this will
not be included in the form despite being specified in
:attr:`~ModelFormOptions.fields`.
Either :attr:`~ModelFormOptions.fields` or
:attr:`~ModelFormOptions.exclude` must be set. If neither are set, an
:class:`~django.core.exceptions.ImproperlyConfigured` exception will be
raised.
``formfield_callback``
----------------------
.. attribute:: ModelFormOptions.formfield_callback
A function or callable that takes a model field and returns a
:class:`django.forms.Field` object.
``help_texts``
--------------
.. attribute:: ModelFormOptions.help_texts
A dictionary that maps a model field name to a help text string.
When a field is not specified, Django will fall back on that model field's
:attr:`~django.db.models.Field.help_text`.
``labels``
----------
.. attribute:: ModelFormOptions.labels
A dictionary that maps a model field names to a label string.
When a field is not specified, Django will fall back on that model field's
:attr:`~django.db.models.Field.verbose_name` and then the field's attribute
name.
``localized_fields``
--------------------
.. attribute:: ModelFormOptions.localized_fields
A tuple or list of :attr:`~ModelFormOptions.model` field names to be
localized. The value ``'__all__'`` can be used to specify that all fields
should be localized.
By default, form fields are not localized, see
:ref:`enabling localization of fields
<modelforms-enabling-localization-of-fields>` for more details.
``model``
---------
.. attribute:: ModelFormOptions.model
Required. The :class:`django.db.models.Model` to be used for the
:class:`~django.forms.ModelForm`.
``widgets``
-----------
.. attribute:: ModelFormOptions.widgets
A dictionary that maps a model field name to a
:class:`django.forms.Widget`.
When a field is not specified, Django will fall back on the default widget
for that particular type of :class:`django.db.models.Field`.
Model form factory functions
============================
.. currentmodule:: django.forms.models
``modelform_factory``
=====================
---------------------
.. function:: modelform_factory(model, form=ModelForm, fields=None, exclude=None, formfield_callback=None, widgets=None, localized_fields=None, labels=None, help_texts=None, error_messages=None, field_classes=None)
@ -51,7 +224,7 @@ Model Form API reference. For introductory material about model forms, see the
in an :exc:`~django.core.exceptions.ImproperlyConfigured` exception.
``modelformset_factory``
========================
------------------------
.. function:: modelformset_factory(model, form=ModelForm, formfield_callback=None, formset=BaseModelFormSet, extra=1, can_delete=False, can_order=False, max_num=None, fields=None, exclude=None, widgets=None, validate_max=False, localized_fields=None, labels=None, help_texts=None, error_messages=None, min_num=None, validate_min=False, field_classes=None, absolute_max=None, can_delete_extra=True, renderer=None, edit_only=False)
@ -74,7 +247,7 @@ Model Form API reference. For introductory material about model forms, see the
See :ref:`model-formsets` for example usage.
``inlineformset_factory``
=========================
-------------------------
.. function:: inlineformset_factory(parent_model, model, form=ModelForm, formset=BaseInlineFormSet, fk_name=None, fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, widgets=None, validate_max=False, localized_fields=None, labels=None, help_texts=None, error_messages=None, min_num=None, validate_min=False, field_classes=None, absolute_max=None, can_delete_extra=True, renderer=None, edit_only=False)

View File

@ -164,7 +164,7 @@ Messages to this logger have the following extra context:
* ``status_code``: The HTTP response code associated with the request.
* ``request``: The request object (a :py:class:`socket.socket`) that generated
* ``request``: The request object (a :class:`socket.socket`) that generated
the logging message.
.. _django-template-logger:
@ -215,27 +215,28 @@ messages during filesystem inspection and event subscription processes.
``django.contrib.auth``
~~~~~~~~~~~~~~~~~~~~~~~
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.
Log messages related to :doc:`/ref/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``
~~~~~~~~~~~~~~~~~~~~~~
Log messages related to :doc:`contrib/gis/index` at various points: during the
loading of external GeoSpatial libraries (GEOS, GDAL, etc.) and when reporting
errors. Each ``ERROR`` log record includes the caught exception and relevant
contextual data.
Log messages related to :doc:`/ref/contrib/gis/index` at various points: during
the loading of external GeoSpatial libraries (GEOS, GDAL, etc.) and when
reporting errors. Each ``ERROR`` log record includes the caught exception and
relevant contextual data.
.. _django-dispatch-logger:
``django.dispatch``
~~~~~~~~~~~~~~~~~~~
This logger is used in :doc:`signals`, specifically within the
This logger is used in :doc:`/ref/signals`, specifically within the
:mod:`~django.dispatch.Signal` class, to report issues when dispatching a
signal to a connected receiver. The ``ERROR`` log record includes the caught
exception as ``exc_info`` and adds the following extra context:

View File

@ -6,9 +6,9 @@ Conditional Expressions
Conditional expressions let you use :keyword:`if` ... :keyword:`elif` ...
:keyword:`else` logic within filters, annotations, aggregations, and updates. A
conditional expression evaluates a series of conditions for each row of a
table and returns the matching result expression. Conditional expressions can
also be combined and nested like other :doc:`expressions <expressions>`.
conditional expression evaluates a series of conditions for each row of a table
and returns the matching result expression. Conditional expressions can also be
combined and nested like other :doc:`expressions </ref/models/expressions>`.
The conditional expression classes
==================================

View File

@ -7,8 +7,8 @@ Database Functions
The classes documented below provide a way for users to use functions provided
by the underlying database as annotations, aggregations, or filters in Django.
Functions are also :doc:`expressions <expressions>`, so they can be used and
combined with other expressions like :ref:`aggregate functions
Functions are also :doc:`expressions </ref/models/expressions>`, so they can be
used and combined with other expressions like :ref:`aggregate functions
<aggregation-functions>`.
We'll be using the following model in examples of each function::

View File

@ -340,7 +340,8 @@ extra attribute ``field_lower`` produced, roughly, from the following SQL:
...
LOWER("db_table"."field") as "field_lower"
See :doc:`database-functions` for a list of built-in database functions.
See :doc:`/ref/models/database-functions` for a list of built-in database
functions.
The ``Func`` API is as follows:
@ -563,7 +564,7 @@ values into their corresponding database type.
If no :ref:`output_field<output-field>` is specified, it will be inferred from
the type of the provided ``value`` for many common types. For example, passing
an instance of :py:class:`datetime.datetime` as ``value`` defaults
an instance of :class:`datetime.datetime` as ``value`` defaults
``output_field`` to :class:`~django.db.models.DateTimeField`.
``ExpressionWrapper()`` expressions
@ -582,7 +583,7 @@ Conditional expressions
Conditional expressions allow you to use :keyword:`if` ... :keyword:`elif` ...
:keyword:`else` logic in queries. Django natively supports SQL ``CASE``
expressions. For more details see :doc:`conditional-expressions`.
expressions. For more details see :doc:`/ref/models/conditional-expressions`.
``Subquery()`` expressions
--------------------------
@ -1094,7 +1095,7 @@ calling the appropriate methods on the wrapped expression.
Tells Django which value should be returned when the expression is used
to apply a function over an empty result set. Defaults to
:py:data:`NotImplemented` which forces the expression to be computed on
:data:`NotImplemented` which forces the expression to be computed on
the database.
.. attribute:: set_returning

View File

@ -1434,7 +1434,7 @@ Python native format: dictionaries, lists, strings, numbers, booleans and
.. attribute:: JSONField.encoder
An optional :py:class:`json.JSONEncoder` subclass to serialize data types
An optional :class:`json.JSONEncoder` subclass to serialize data types
not supported by the standard JSON serializer (e.g. ``datetime.datetime``
or :class:`~python:uuid.UUID`). For example, you can use the
:class:`~django.core.serializers.json.DjangoJSONEncoder` class.
@ -1443,7 +1443,7 @@ Python native format: dictionaries, lists, strings, numbers, booleans and
.. attribute:: JSONField.decoder
An optional :py:class:`json.JSONDecoder` subclass to deserialize the value
An optional :class:`json.JSONDecoder` subclass to deserialize the value
retrieved from the database. The value will be in the format chosen by the
custom encoder (most often a string). Your deserialization may need to
account for the fact that you can't be certain of the input type. For
@ -1458,7 +1458,7 @@ To query ``JSONField`` in the database, see :ref:`querying-jsonfield`.
.. admonition:: Default value
If you give the field a :attr:`~django.db.models.Field.default`, ensure
it's a callable such as the :py:class:`dict` class or a function that
it's a callable such as the :class:`dict` class or a function that
returns a fresh object each time. Incorrectly using a mutable object like
``default={}`` or ``default=[]`` creates a mutable default that is shared
between all instances.
@ -1483,8 +1483,8 @@ To query ``JSONField`` in the database, see :ref:`querying-jsonfield`.
.. admonition:: Oracle users
Oracle Database does not support storing JSON scalar values. Only JSON
objects and arrays (represented in Python using :py:class:`dict` and
:py:class:`list`) are supported.
objects and arrays (represented in Python using :class:`dict` and
:class:`list`) are supported.
``PositiveBigIntegerField``
---------------------------
@ -2440,7 +2440,7 @@ Field API reference
.. attribute:: descriptor_class
A class implementing the :py:ref:`descriptor protocol <descriptors>`
A class implementing the :ref:`descriptor protocol <descriptors>`
that is instantiated and assigned to the model instance attribute. The
constructor must accept a single argument, the ``Field`` instance.
Overriding this class attribute allows for customizing the get and set

View File

@ -889,7 +889,7 @@ Attributes
.. attribute:: HttpResponse.cookies
A :py:obj:`http.cookies.SimpleCookie` object holding the cookies included
A :obj:`http.cookies.SimpleCookie` object holding the cookies included
in the response.
.. attribute:: HttpResponse.headers
@ -952,7 +952,7 @@ Methods
``"text/html; charset=utf-8"``.
``status`` is the :rfc:`HTTP status code <9110#section-15>` for the
response. You can use Python's :py:class:`http.HTTPStatus` for meaningful
response. You can use Python's :class:`http.HTTPStatus` for meaningful
aliases, such as ``HTTPStatus.NO_CONTENT``.
``reason`` is the HTTP response phrase. If not provided, a default phrase
@ -1187,7 +1187,7 @@ Custom response classes
~~~~~~~~~~~~~~~~~~~~~~~
If you find yourself needing a response class that Django doesn't provide, you
can create it with the help of :py:class:`http.HTTPStatus`. For example::
can create it with the help of :class:`http.HTTPStatus`. For example::
from http import HTTPStatus
from django.http import HttpResponse

View File

@ -1225,14 +1225,14 @@ attribute and calling the result ``country_list``.
``{% regroup %}`` produces a list (in this case, ``country_list``) of
**group objects**. Group objects are instances of
:py:func:`~collections.namedtuple` with two fields:
:func:`~collections.namedtuple` with two fields:
* ``grouper`` -- the item that was grouped by (e.g., the string "India" or
"Japan").
* ``list`` -- a list of all items in this group (e.g., a list of all cities
with country='India').
Because ``{% regroup %}`` produces :py:func:`~collections.namedtuple` objects,
Because ``{% regroup %}`` produces :func:`~collections.namedtuple` objects,
you can also write the previous example as:
.. code-block:: html+django
@ -1839,7 +1839,7 @@ For example:
{{ value|date:"D d M Y" }}
If ``value`` is a :py:class:`~datetime.datetime` object (e.g., the result of
If ``value`` is a :class:`~datetime.datetime` object (e.g., the result of
``datetime.datetime.now()``), the output will be the string
``'Wed 09 Jan 2008'``.
@ -2736,7 +2736,7 @@ specifier for the ``de`` locale as shipped with Django is ``"H:i"``).
The ``time`` filter will only accept parameters in the format string that
relate to the time of day, not the date. If you need to format a ``date``
value, use the :tfilter:`date` filter instead (or along with :tfilter:`time` if
you need to render a full :py:class:`~datetime.datetime` value).
you need to render a full :class:`~datetime.datetime` value).
There is one exception the above rule: When passed a ``datetime`` value with
attached timezone information (a :ref:`time-zone-aware

View File

@ -268,7 +268,7 @@ Use strings when creating templates manually::
But the common case is to read templates from the filesystem. If your template
files are not stored with a UTF-8 encoding, adjust the :setting:`TEMPLATES`
setting. The built-in :py:mod:`~django.template.backends.django` backend
setting. The built-in :mod:`~django.template.backends.django` backend
provides the ``'file_charset'`` option to change the encoding used to read
files from disk.

View File

@ -95,7 +95,7 @@ Returns an element for inclusion in ``urlpatterns``. For example::
The ``route`` argument should be a string or
:func:`~django.utils.translation.gettext_lazy` (see
:ref:`translating-urlpatterns`) that contains a regular expression compatible
with Python's :py:mod:`re` module. Strings typically use raw string syntax
with Python's :mod:`re` module. Strings typically use raw string syntax
(``r''``) so that they can contain sequences like ``\d`` without the need to
escape the backslash with another backslash. When a match is made, captured
groups from the regular expression are passed to the view -- as named arguments
@ -104,7 +104,7 @@ passed as strings, without any type conversion.
When a ``route`` ends with ``$`` the whole requested URL, matching against
:attr:`~django.http.HttpRequest.path_info`, must match the regular expression
pattern (:py:func:`re.fullmatch` is used).
pattern (:func:`re.fullmatch` is used).
The ``view``, ``kwargs`` and ``name`` arguments are the same as for
:func:`~django.urls.path`.

View File

@ -352,7 +352,7 @@ compatibility
An optional string containing the MIME type of the stylesheet. If not
specified, Django will attempt to guess it by using Python's
:py:func:`mimetypes.guess_type`. Use ``mimetype=None`` if you don't
:func:`mimetypes.guess_type`. Use ``mimetype=None`` if you don't
want your stylesheet to have a MIME type specified.
.. attribute:: media
@ -532,7 +532,7 @@ compatibility
# set a value manually, that will persist on the instance until cleared
person.friends = ["Huckleberry Finn", "Tom Sawyer"]
Because of the way the :py:ref:`descriptor protocol
Because of the way the :ref:`descriptor protocol
<descriptor-invocation>` works, using ``del`` (or ``delattr``) on a
``cached_property`` that hasn't been accessed raises ``AttributeError``.
@ -560,7 +560,7 @@ compatibility
.. class:: classproperty(method=None)
Similar to :py:func:`@classmethod <classmethod>`, the ``@classproperty``
Similar to :func:`@classmethod <classmethod>`, the ``@classproperty``
decorator converts the result of a method with a single ``cls`` argument
into a property that can be accessed directly from the class.

View File

@ -448,7 +448,7 @@ Requests and Responses
* Added :class:`~django.http.HttpResponse` methods
:meth:`~django.http.HttpResponse.readable` and
:meth:`~django.http.HttpResponse.seekable` to make an instance a
stream-like object and allow wrapping it with :py:class:`io.TextIOWrapper`.
stream-like object and allow wrapping it with :class:`io.TextIOWrapper`.
* Added the :attr:`HttpRequest.content_type
<django.http.HttpRequest.content_type>` and

View File

@ -332,7 +332,8 @@ Models
* :class:`~django.db.models.ImageField` now has a default
:data:`~django.core.validators.validate_image_file_extension` validator.
(This validator moved to the form field in :doc:`Django 1.11.2 <1.11.2>`.)
(This validator moved to the form field in :doc:`Django 1.11.2
</releases/1.11.2>`.)
* Added support for time truncation to
:class:`~django.db.models.functions.Trunc` functions.

View File

@ -266,7 +266,7 @@ and in Django 1.5 will raise an ``ImproperlyConfigured`` exception.
Everything else
---------------
Django :doc:`1.1 <1.1>` and :doc:`1.2 <1.2>` added
Django :doc:`1.1 </releases/1.1>` and :doc:`1.2 </releases/1.2>` added
lots of big ticket items to Django, like multiple-database support,
model validation, and a session-based messages framework. However,
this focus on big features came at the cost of lots of smaller

View File

@ -5,4 +5,5 @@ Django 1.8.11 release notes
*March 5, 2016*
Django 1.8.11 fixes a regression on Python 2 in the 1.8.10 security release
where ``utils.http.is_safe_url()`` crashes on bytestring URLs (:ticket:`26308`).
where ``utils.http.is_safe_url()`` crashes on bytestring URLs
(:ticket:`26308`).

View File

@ -275,7 +275,7 @@ Cryptography
* The ``max_age`` parameter of the
:meth:`django.core.signing.TimestampSigner.unsign` method now also accepts a
:py:class:`datetime.timedelta` object.
:class:`datetime.timedelta` object.
Database backends
~~~~~~~~~~~~~~~~~
@ -384,7 +384,7 @@ Generic Views
* Placeholders in :attr:`ModelFormMixin.success_url
<django.views.generic.edit.ModelFormMixin.success_url>` now support the
Python :py:meth:`str.format` syntax. The legacy ``%(<foo>)s`` syntax is still
Python :meth:`str.format` syntax. The legacy ``%(<foo>)s`` syntax is still
supported but will be removed in Django 1.10.
Internationalization
@ -753,7 +753,7 @@ Management commands that only accept positional arguments
If you have written a custom management command that only accepts positional
arguments and you didn't specify the ``args`` command variable, you might get
an error like ``Error: unrecognized arguments: ...``, as variable parsing is
now based on :py:mod:`argparse` which doesn't implicitly accept positional
now based on :mod:`argparse` which doesn't implicitly accept positional
arguments. You can make your command backwards compatible by simply setting the
``args`` class variable. However, if you don't have to keep compatibility with
older Django versions, it's better to implement the new
@ -766,10 +766,10 @@ Custom test management command arguments through test runner
The method to add custom arguments to the ``test`` management command through
the test runner has changed. Previously, you could provide an ``option_list``
class variable on the test runner to add more arguments (à la
:py:mod:`optparse`). Now to implement the same behavior, you have to create an
:mod:`optparse`). Now to implement the same behavior, you have to create an
``add_arguments(cls, parser)`` class method on the test runner and call
``parser.add_argument`` to add any custom arguments, as parser is now an
:py:class:`argparse.ArgumentParser` instance.
:class:`argparse.ArgumentParser` instance.
Model check ensures auto-generated column names are within limits specified by database
---------------------------------------------------------------------------------------
@ -1407,7 +1407,7 @@ in Django 1.10:
Extending management command arguments through ``Command.option_list``
----------------------------------------------------------------------
Management commands now use :py:mod:`argparse` instead of :py:mod:`optparse` to
Management commands now use :mod:`argparse` instead of :mod:`optparse` to
parse command-line arguments passed to commands. This also means that the way
to add custom arguments to commands has changed: instead of extending the
``option_list`` class list, you should now override the

View File

@ -5,4 +5,5 @@ Django 1.9.4 release notes
*March 5, 2016*
Django 1.9.4 fixes a regression on Python 2 in the 1.9.3 security release
where ``utils.http.is_safe_url()`` crashes on bytestring URLs (:ticket:`26308`).
where ``utils.http.is_safe_url()`` crashes on bytestring URLs
(:ticket:`26308`).

View File

@ -285,7 +285,7 @@ Models
* The new :attr:`.Field.descriptor_class` attribute allows model fields to
customize the get and set behavior by overriding their
:py:ref:`descriptors <descriptors>`.
:ref:`descriptors <descriptors>`.
* :class:`~django.db.models.Avg` and :class:`~django.db.models.Sum` now support
the ``distinct`` argument.

View File

@ -43,7 +43,7 @@ Bugfixes
* Fixed a regression in Django 3.1 where
:exc:`ProtectedError.protected_objects <django.db.models.ProtectedError>` and
:exc:`RestrictedError.restricted_objects <django.db.models.RestrictedError>`
attributes returned iterators instead of :py:class:`set` of objects
attributes returned iterators instead of :class:`set` of objects
(:ticket:`32107`).
* Fixed a regression in Django 3.1.2 that caused incorrect form input layout on

View File

@ -407,7 +407,7 @@ Models
SQL on MySQL by using ``DELETE`` instead of ``TRUNCATE`` statements for
tables which don't require resetting sequences.
* SQLite functions are now marked as :py:meth:`deterministic
* SQLite functions are now marked as :meth:`deterministic
<sqlite3.Connection.create_function>` on Python 3.8+. This allows using them
in check constraints and partial indexes.

View File

@ -406,11 +406,11 @@ Models
* :class:`Value() <django.db.models.Value>` expression now
automatically resolves its ``output_field`` to the appropriate
:class:`Field <django.db.models.Field>` subclass based on the type of
its provided ``value`` for :py:class:`bool`, :py:class:`bytes`,
:py:class:`float`, :py:class:`int`, :py:class:`str`,
:py:class:`datetime.date`, :py:class:`datetime.datetime`,
:py:class:`datetime.time`, :py:class:`datetime.timedelta`,
:py:class:`decimal.Decimal`, and :py:class:`uuid.UUID` instances. As a
its provided ``value`` for :class:`bool`, :class:`bytes`,
:class:`float`, :class:`int`, :class:`str`,
:class:`datetime.date`, :class:`datetime.datetime`,
:class:`datetime.time`, :class:`datetime.timedelta`,
:class:`decimal.Decimal`, and :class:`uuid.UUID` instances. As a
consequence, resolving an ``output_field`` for database functions and
combined expressions may now crash with mixed types when using ``Value()``.
You will need to explicitly set the ``output_field`` in such cases.
@ -519,11 +519,11 @@ Tests
* Objects assigned to class attributes in :meth:`.TestCase.setUpTestData` are
now isolated for each test method. Such objects are now required to support
creating deep copies with :py:func:`copy.deepcopy`. Assigning objects which
creating deep copies with :func:`copy.deepcopy`. Assigning objects which
don't support ``deepcopy()`` is deprecated and will be removed in Django 4.1.
* :class:`~django.test.runner.DiscoverRunner` now enables
:py:mod:`faulthandler` by default. This can be disabled by using the
:mod:`faulthandler` by default. This can be disabled by using the
:option:`test --no-faulthandler` option.
* :class:`~django.test.runner.DiscoverRunner` and the
@ -703,8 +703,8 @@ Miscellaneous
removed. Please use :func:`urllib.parse.parse_qsl` instead.
* ``django.test.utils.TestContextDecorator`` now uses
:py:meth:`~unittest.TestCase.addCleanup` so that cleanups registered in the
:py:meth:`~unittest.TestCase.setUp` method are called before
:meth:`~unittest.TestCase.addCleanup` so that cleanups registered in the
:meth:`~unittest.TestCase.setUp` method are called before
``TestContextDecorator.disable()``.
* ``SessionMiddleware`` now raises a
@ -758,7 +758,7 @@ Miscellaneous
-------------
* Assigning objects which don't support creating deep copies with
:py:func:`copy.deepcopy` to class attributes in
:func:`copy.deepcopy` to class attributes in
:meth:`.TestCase.setUpTestData` is deprecated.
* Using a boolean value in :attr:`.BaseCommand.requires_system_checks` is

View File

@ -289,7 +289,7 @@ Management Commands
* On PostgreSQL, :djadmin:`dbshell` now supports specifying a password file.
* The :djadmin:`shell` command now respects :py:data:`sys.__interactivehook__`
* The :djadmin:`shell` command now respects :data:`sys.__interactivehook__`
at startup. This allows loading shell history between interactive sessions.
As a consequence, ``readline`` is no longer loaded if running in *isolated*
mode.
@ -349,7 +349,7 @@ Signals
* The new ``stdout`` argument for :func:`~django.db.models.signals.pre_migrate`
and :func:`~django.db.models.signals.post_migrate` signals allows redirecting
output to a stream-like object. It should be preferred over
:py:data:`sys.stdout` and :py:func:`print` when emitting verbose output in
:data:`sys.stdout` and :func:`print` when emitting verbose output in
order to allow proper capture when testing.
Templates
@ -370,7 +370,7 @@ Tests
* The :option:`test --buffer` option now supports parallel tests.
* The new ``logger`` argument to :class:`~django.test.runner.DiscoverRunner`
allows a Python :py:ref:`logger <logger>` to be used for logging.
allows a Python :ref:`logger <logger>` to be used for logging.
* The new :meth:`.DiscoverRunner.log` method provides a way to log messages
that uses the ``DiscoverRunner.logger``, or prints to the console if not set.

View File

@ -536,7 +536,7 @@ Miscellaneous
* :class:`~django.test.runner.DiscoverRunner` now returns a non-zero error code
for unexpected successes from tests marked with
:py:func:`unittest.expectedFailure`.
:func:`unittest.expectedFailure`.
* :class:`~django.middleware.csrf.CsrfViewMiddleware` no longer masks the CSRF
cookie like it does the CSRF token in the DOM.
@ -608,7 +608,7 @@ Features deprecated in 4.1
Log out via GET
---------------
Logging out via ``GET`` requests to the :py:class:`built-in logout view
Logging out via ``GET`` requests to the :class:`built-in logout view
<django.contrib.auth.views.LogoutView>` is deprecated. Use ``POST`` requests
instead.

7
docs/releases/4.2.24.txt Normal file
View File

@ -0,0 +1,7 @@
===========================
Django 4.2.24 release notes
===========================
*September 3, 2025*
Django 4.2.24 fixes a security issue with severity "high" in 4.2.23.

View File

@ -475,8 +475,8 @@ Miscellaneous
* Support for ``PROJ`` < 5 is removed.
* :class:`~django.core.mail.backends.smtp.EmailBackend` now verifies a
:py:attr:`hostname <ssl.SSLContext.check_hostname>` and
:py:attr:`certificates <ssl.SSLContext.verify_mode>`. If you need the
:attr:`hostname <ssl.SSLContext.check_hostname>` and
:attr:`certificates <ssl.SSLContext.verify_mode>`. If you need the
previous behavior that is less restrictive and not recommended, subclass
``EmailBackend`` and override the ``ssl_context`` property.
@ -564,7 +564,7 @@ Miscellaneous
* The ``BaseUserManager.make_random_password()`` method is deprecated. See
`recipes and best practices
<https://docs.python.org/3/library/secrets.html#recipes-and-best-practices>`_
for using Python's :py:mod:`secrets` module to generate passwords.
for using Python's :mod:`secrets` module to generate passwords.
* The ``length_is`` template filter is deprecated in favor of :tfilter:`length`
and the ``==`` operator within an :ttag:`{% if %}<if>` tag. For example

7
docs/releases/5.1.12.txt Normal file
View File

@ -0,0 +1,7 @@
===========================
Django 5.1.12 release notes
===========================
*September 3, 2025*
Django 5.1.12 fixes a security issue with severity "high" in 5.1.11.

View File

@ -382,7 +382,7 @@ Miscellaneous
* ``django.utils.text.Truncator`` used by :tfilter:`truncatechars_html` and
:tfilter:`truncatewords_html` template filters now uses
:py:class:`html.parser.HTMLParser` subclasses. This results in a more robust
:class:`html.parser.HTMLParser` subclasses. This results in a more robust
and faster operation, but there may be small differences in the output.
* The undocumented ``django.urls.converters.get_converter()`` function is

View File

@ -2,11 +2,14 @@
Django 5.2.6 release notes
==========================
*Expected September 3, 2025*
*September 3, 2025*
Django 5.2.6 fixes several bugs in 5.2.5.
Django 5.2.6 fixes a security issue with severity "high" and several bugs in
5.2.5.
Bugfixes
========
* ...
* Fixed a bug where using ``QuerySet.values()`` or ``values_list()`` with a
``ForeignObject`` composed of multiple fields returned incorrect results
instead of tuples of the referenced fields (:ticket:`36431`).

View File

@ -380,8 +380,8 @@ 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
:data:`NotImplemented` in ``__add__`` for non-string right-hand side
values. This aligns with the :class:`str` addition behavior and allows
``__radd__`` to be used if available.
* :func:`~django.utils.html.format_html_join` now supports taking an iterable

View File

@ -72,22 +72,23 @@ The resulting ``Content-Security-Policy`` header would be set to:
To get started, follow the :doc:`CSP how-to guide </howto/csp>`. For in-depth
guidance, see the :ref:`CSP security overview <security-csp>` and the
:doc:`reference docs </ref/csp>`.
:doc:`reference docs </ref/csp>`, which include details about decorators to
override or disable policies on a per-view basis.
Adoption of Python's modern email API
-------------------------------------
Email handling in Django now uses Python's modern email API, introduced in
Python 3.6. This API, centered around the
:py:class:`email.message.EmailMessage` class, offers a cleaner and
:class:`email.message.EmailMessage` class, offers a cleaner and
Unicode-friendly interface for composing and sending emails. It replaces use of
Python's older legacy (``Compat32``) API, which relied on lower-level MIME
classes (from :py:mod:`email.mime`) and required more manual handling of
classes (from :mod:`email.mime`) and required more manual handling of
message structure and encoding.
Notably, the return type of the :class:`EmailMessage.message()
<django.core.mail.EmailMessage>` method is now an instance of Python's
:py:class:`email.message.EmailMessage`. This supports the same API as the
:class:`email.message.EmailMessage`. This supports the same API as the
previous ``SafeMIMEText`` and ``SafeMIMEMultipart`` return types, but is not an
instance of those now-deprecated classes.
@ -228,7 +229,7 @@ Email
* The new ``policy`` argument for :class:`EmailMessage.message()
<django.core.mail.EmailMessage>` allows specifying the email policy, the set
of rules for updating and serializing the representation of the message.
Defaults to :py:data:`email.policy.default`.
Defaults to :data:`email.policy.default`.
* :class:`EmailMessage.attach() <django.core.mail.EmailMessage>` now accepts a
:class:`~email.message.MIMEPart` object from Python's modern email API.
@ -402,6 +403,18 @@ backends.
* :class:`~django.db.backends.base.schema.BaseDatabaseSchemaEditor` and
PostgreSQL backends no longer use ``CASCADE`` when dropping a column.
* ``DatabaseOperations.return_insert_columns()`` and
``DatabaseOperations.fetch_returned_insert_rows()`` methods are renamed to
``returning_columns()`` and ``fetch_returned_rows()``, respectively, to
denote they can be used in the context ``UPDATE … RETURNING`` statements as
well as ``INSERT … RETURNING``.
* The ``DatabaseOperations.fetch_returned_insert_columns()`` method is removed
and the ``fetch_returned_rows()`` method replacing
``fetch_returned_insert_rows()`` expects both a ``cursor`` and
``returning_params`` to be provided just like
``fetch_returned_insert_columns()`` did.
Dropped support for MariaDB 10.5
--------------------------------
@ -439,7 +452,7 @@ Email
* The undocumented ``encoding`` property of
:class:`~django.core.mail.EmailMessage` no longer supports Python legacy
:py:class:`email.charset.Charset` objects.
:class:`email.charset.Charset` objects.
* As the internal implementations of :class:`~django.core.mail.EmailMessage`
and :class:`~django.core.mail.EmailMultiAlternatives` have changed
@ -471,7 +484,7 @@ Miscellaneous
at the end of the output, even without the ``indent`` option set.
* The undocumented ``django.utils.http.parse_header_parameters()`` function is
refactored to use Python's :py:class:`email.message.Message` for parsing.
refactored to use Python's :class:`email.message.Message` for parsing.
Input headers exceeding 10000 characters will now raise :exc:`ValueError`.
* Widgets from :mod:`django.contrib.gis.forms.widgets` now render without
@ -571,7 +584,7 @@ Miscellaneous
``django.core.mail.message.sanitize_address()`` functions are deprecated.
* The ``django.utils.crypto.constant_time_compare()`` function is deprecated
because it is merely an alias of :py:func:`hmac.compare_digest`.
because it is merely an alias of :func:`hmac.compare_digest`.
Features removed in 6.0
=======================

View File

@ -45,6 +45,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
5.1.12
5.1.11
5.1.10
5.1.9
@ -85,6 +86,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
4.2.24
4.2.23
4.2.22
4.2.21

View File

@ -82,6 +82,8 @@ view functions:
* :func:`~django.views.decorators.cache.cache_control`
* :func:`~django.views.decorators.cache.never_cache`
* :func:`~django.views.decorators.common.no_append_slash`
* :func:`~django.views.decorators.csp.csp_override`
* :func:`~django.views.decorators.csp.csp_report_only_override`
* :func:`~django.views.decorators.csrf.csrf_exempt`
* :func:`~django.views.decorators.csrf.csrf_protect`
* :func:`~django.views.decorators.csrf.ensure_csrf_cookie`
@ -312,7 +314,7 @@ Threadlocals and contextvars values are preserved across the boundary in both
directions.
:func:`async_to_sync` is essentially a more powerful version of the
:py:func:`asyncio.run` function in Python's standard library. As well
:func:`asyncio.run` function in Python's standard library. As well
as ensuring threadlocals work, it also enables the ``thread_sensitive`` mode of
:func:`sync_to_async` when that wrapper is used below it.

View File

@ -75,7 +75,7 @@ models defined in your installed apps.
Usage
=====
:doc:`Using Django's default implementation <default>`
:doc:`Using Django's default implementation </topics/auth/default>`
* :ref:`Working with User objects <user-objects>`
* :ref:`Permissions and authorization <topic-authorization>`
@ -84,6 +84,6 @@ Usage
:doc:`API reference for the default implementation </ref/contrib/auth>`
:doc:`Customizing Users and authentication <customizing>`
:doc:`Customizing Users and authentication </topics/auth/customizing>`
:doc:`Password management in Django <passwords>`
:doc:`Password management in Django </topics/auth/passwords>`

View File

@ -5,8 +5,8 @@ Using mixins with class-based views
.. caution::
This is an advanced topic. A working knowledge of :doc:`Django's
class-based views<index>` is advised before exploring these
techniques.
class-based views </topics/class-based-views/index>` is advised before
exploring these techniques.
Django's built-in class-based views provide a lot of functionality,
but some of it you may want to use separately. For instance, you may
@ -120,9 +120,9 @@ but the main one that most people are going to use is
``<app_label>/<model_name>_detail.html``. The ``_detail`` part can be changed
by setting
:attr:`~django.views.generic.detail.SingleObjectTemplateResponseMixin.template_name_suffix`
on a subclass to something else. (For instance, the :doc:`generic edit
views<generic-editing>` use ``_form`` for create and update views, and
``_confirm_delete`` for delete views.)
on a subclass to something else. (For instance, the :doc:`generic edit views
</topics/class-based-views/generic-editing>` use ``_form`` for create and
update views, and ``_confirm_delete`` for delete views.)
``ListView``: working with many Django objects
----------------------------------------------
@ -213,8 +213,8 @@ in the subclass. However if we want our processing to work on a particular
object, identified from the URL, we'll want the functionality provided by
:class:`~django.views.generic.detail.SingleObjectMixin`.
We'll demonstrate this with the ``Author`` model we used in the
:doc:`generic class-based views introduction<generic-display>`.
We'll demonstrate this with the ``Author`` model we used in the :doc:`generic
class-based views introduction </topics/class-based-views/generic-display>`.
.. code-block:: python
:caption: ``views.py``
@ -390,11 +390,11 @@ increasingly complex as you try to do so, and a good rule of thumb is:
.. hint::
Each of your views should use only mixins or views from one of the
groups of generic class-based views: :doc:`detail,
list<generic-display>`, :doc:`editing<generic-editing>` and
date. For example it's fine to combine
:class:`TemplateView` (built in view) with
Each of your views should use only mixins or views from one of the groups
of generic class-based views: :doc:`detail, list
</topics/class-based-views/generic-display>`, :doc:`editing
</topics/class-based-views/generic-editing>` and date. For example it's
fine to combine :class:`TemplateView` (built in view) with
:class:`~django.views.generic.list.MultipleObjectMixin` (generic list), but
you're likely to have problems combining ``SingleObjectMixin`` (generic
detail) with ``MultipleObjectMixin`` (generic list).

View File

@ -1060,7 +1060,7 @@ representation of the JSON scalar ``null`` is the same as SQL ``NULL``, i.e.
``None``. Therefore, it can be hard to distinguish between them.
This only applies to ``None`` as the top-level value of the field. If ``None``
is inside a :py:class:`list` or :py:class:`dict`, it will always be interpreted
is inside a :class:`list` or :class:`dict`, it will always be interpreted
as JSON ``null``.
When querying, ``None`` value will always be interpreted as JSON ``null``. To

View File

@ -113,7 +113,7 @@ Django provides a single API to control database transactions.
durability and can be achieved by setting ``durable=True``. If the
``atomic`` block is nested within another it raises a ``RuntimeError``.
``atomic`` is usable both as a :py:term:`decorator`::
``atomic`` is usable both as a :term:`decorator`::
from django.db import transaction
@ -123,7 +123,7 @@ Django provides a single API to control database transactions.
# This code executes inside a transaction.
do_stuff()
and as a :py:term:`context manager`::
and as a :term:`context manager`::
from django.db import transaction

View File

@ -418,11 +418,11 @@ The class has the following methods:
The keyword argument ``policy`` allows specifying the set of rules for
updating and serializing the representation of the message. It must be an
:py:mod:`email.policy.Policy <email.policy>` object. Defaults to
:py:data:`email.policy.default`. In certain cases you may want to use
:py:data:`~email.policy.SMTP`, :py:data:`~email.policy.SMTPUTF8` or a custom
:mod:`email.policy.Policy <email.policy>` object. Defaults to
:data:`email.policy.default`. In certain cases you may want to use
:data:`~email.policy.SMTP`, :data:`~email.policy.SMTPUTF8` or a custom
policy. For example, :class:`django.core.mail.backends.smtp.EmailBackend`
uses the :py:data:`~email.policy.SMTP` policy to ensure ``\r\n`` line endings
uses the :data:`~email.policy.SMTP` policy to ensure ``\r\n`` line endings
as required by the SMTP protocol.
If you ever need to extend Django's :class:`~django.core.mail.EmailMessage`
@ -432,7 +432,7 @@ The class has the following methods:
.. versionchanged:: 6.0
The ``policy`` keyword argument was added and the return type was updated
to an instance of :py:class:`~email.message.EmailMessage`.
to an instance of :class:`~email.message.EmailMessage`.
* ``recipients()`` returns a list of all the recipients of the message,
whether they're recorded in the ``to``, ``cc`` or ``bcc`` attributes. This

View File

@ -50,8 +50,8 @@ following example will create a formset class to display two blank forms:
Formsets can be iterated and indexed, accessing forms in the order they were
created. You can reorder the forms by overriding the default
:py:meth:`iteration <object.__iter__>` and
:py:meth:`indexing <object.__getitem__>` behavior if needed.
:meth:`iteration <object.__iter__>` and
:meth:`indexing <object.__getitem__>` behavior if needed.
.. _formsets-initial-data:

View File

@ -38,6 +38,8 @@ For example:
>>> article = Article.objects.get(pk=1)
>>> form = ArticleForm(instance=article)
.. _model-form-field-types:
Field types
-----------
@ -683,6 +685,8 @@ the field declaratively and setting its ``validators`` parameter::
See the :doc:`form field documentation </ref/forms/fields>` for more
information on fields and their arguments.
.. _modelforms-enabling-localization-of-fields:
Enabling localization of fields
-------------------------------

View File

@ -129,7 +129,7 @@ have more than a single parameter. If you used positional interpolation,
translations wouldn't be able to reorder placeholder text.
Since string extraction is done by the ``xgettext`` command, only syntaxes
supported by ``gettext`` are supported by Django. Python :py:ref:`f-strings
supported by ``gettext`` are supported by Django. Python :ref:`f-strings
<f-strings>` cannot be used directly with ``gettext`` functions because
f-string expressions are evaluated before they reach ``gettext``. This means
``_(f"Welcome {name}")`` will not work as expected, as the variable is

View File

@ -204,7 +204,7 @@ therefore have performance implications, and the more expensive the work
concerned, the more there is to gain through laziness.
Python provides a number of tools for lazy evaluation, particularly through the
:py:term:`generator` and :py:term:`generator expression` constructs. It's worth
:term:`generator` and :term:`generator expression` constructs. It's worth
reading up on laziness in Python to discover opportunities for making use of
lazy patterns in your code.

View File

@ -44,7 +44,7 @@ by using an environment variable, :envvar:`DJANGO_SETTINGS_MODULE`.
The value of :envvar:`DJANGO_SETTINGS_MODULE` should be in Python path syntax,
e.g. ``mysite.settings``. Note that the settings module should be on the
Python :py:data:`sys.path`.
Python :data:`sys.path`.
The ``django-admin`` utility

View File

@ -116,7 +116,7 @@ generate signatures. You can use a different secret by passing it to the
separate values. ``sep`` cannot be in the :rfc:`URL safe base64 alphabet
<4648#section-5>`. This alphabet contains alphanumeric characters, hyphens,
and underscores. ``algorithm`` must be an algorithm supported by
:py:mod:`hashlib`, it defaults to ``'sha256'``. ``fallback_keys`` is a list
:mod:`hashlib`, it defaults to ``'sha256'``. ``fallback_keys`` is a list
of additional values used to validate signed data, defaults to
:setting:`SECRET_KEY_FALLBACKS`.
@ -192,7 +192,7 @@ created within a specified period of time:
Checks if ``value`` was signed less than ``max_age`` seconds ago,
otherwise raises ``SignatureExpired``. The ``max_age`` parameter can
accept an integer or a :py:class:`datetime.timedelta` object.
accept an integer or a :class:`datetime.timedelta` object.
.. method:: sign_object(obj, serializer=JSONSerializer, compress=False)
@ -203,7 +203,7 @@ created within a specified period of time:
Checks if ``signed_obj`` was signed less than ``max_age`` seconds ago,
otherwise raises ``SignatureExpired``. The ``max_age`` parameter can
accept an integer or a :py:class:`datetime.timedelta` object.
accept an integer or a :class:`datetime.timedelta` object.
.. _signing-complex-data:

Some files were not shown because too many files have changed in this diff Show More