Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
ticket-XXXXX

#### Branch description
<!-- Provide a concise overview of the issue or rationale behind the proposed changes. 5 word minimum. -->
<!-- Provide a concise overview of the issue or rationale behind the proposed changes. Minimum five words. -->

#### AI Assistance Disclosure (REQUIRED)
<!-- Select exactly ONE of the following: -->
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/admin/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def delete_selected(modeladmin, request, queryset):
This action first displays a confirmation page which shows all the
deletable objects, or, if the user has no permission one of the related
childs (foreignkeys), a "permission denied" message.
children (foreignkeys), a "permission denied" message.
Next, it deletes all selected objects and redirects back to the change
list.
Expand Down
6 changes: 3 additions & 3 deletions django/contrib/admin/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2563,14 +2563,14 @@ def history_view(self, request, object_id, extra_context=None):
# First check if the user can see this history.
model = self.model
obj = self.get_object(request, unquote(object_id))
if not self.has_view_or_change_permission(request, obj):
raise PermissionDenied

if obj is None:
return self._get_obj_does_not_exist_redirect(
request, model._meta, object_id
)

if not self.has_view_or_change_permission(request, obj):
raise PermissionDenied

# Then get the history for this object.
app_label = self.opts.app_label
action_list = (
Expand Down
26 changes: 20 additions & 6 deletions django/contrib/admin/sites.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.contrib.admin.views.autocomplete import AutocompleteJsonView
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_not_required
from django.core.exceptions import ImproperlyConfigured
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.db.models.base import ModelBase
from django.http import Http404, HttpResponsePermanentRedirect, HttpResponseRedirect
from django.template.response import TemplateResponse
Expand Down Expand Up @@ -256,10 +256,6 @@ def inner(request, *args, **kwargs):
return update_wrapper(inner, view)

def get_urls(self):
# Since this module gets imported in the application's root package,
# it cannot import models from other applications at the module level,
# and django.contrib.contenttypes.views imports ContentType.
from django.contrib.contenttypes import views as contenttype_views
from django.urls import include, path, re_path

def wrap(view, cacheable=False):
Expand Down Expand Up @@ -290,7 +286,7 @@ def wrapper(*args, **kwargs):
path("jsi18n/", wrap(self.i18n_javascript, cacheable=True), name="jsi18n"),
path(
"r/<path:content_type_id>/<path:object_id>/",
wrap(contenttype_views.shortcut),
wrap(self.shortcut_view),
name="view_on_site",
),
]
Expand Down Expand Up @@ -451,6 +447,24 @@ def login(self, request, extra_context=None):
def autocomplete_view(self, request):
return AutocompleteJsonView.as_view(admin_site=self)(request)

def shortcut_view(self, request, content_type_id, object_id):
from django.contrib.contenttypes import views as contenttype_views
from django.contrib.contenttypes.models import ContentType

try:
content_type = ContentType.objects.get_for_id(int(content_type_id))
except (ContentType.DoesNotExist, ValueError):
pass
else:
model_class = content_type.model_class()
if (
model_class is not None
and self.is_registered(model_class)
and not self.get_model_admin(model_class).has_view_permission(request)
):
raise PermissionDenied
return contenttype_views.shortcut(request, content_type_id, object_id)

@no_append_slash
def catch_all_view(self, request, url):
if settings.APPEND_SLASH and not url.endswith("/"):
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/gis/db/backends/spatialite/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def rttopo_version(self):

def geom_lib_version(self):
"""
Return the version of the version-dependant geom library used by
Return the version of the version-dependent geom library used by
SpatiaLite.
"""
if self.spatial_version >= (5,):
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/gis/db/models/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ def __set__(self, instance, value):
% (instance.__class__.__name__, gtype, type(value))
)

# Setting the objects dictionary with the value, and returning.
# Setting the object's dictionary with the value, and returning.
instance.__dict__[self.field.attname] = value
return value
2 changes: 1 addition & 1 deletion django/contrib/gis/gdal/srs.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def __getitem__(self, target):
4326
>>> print(srs['TOWGS84', 4]) # the fourth value in this wkt
0
>>> # For the units authority, have to use the pipe symbole.
>>> # For the units authority, have to use the pipe symbol.
>>> print(srs['UNIT|AUTHORITY'])
EPSG
>>> print(srs['UNIT|AUTHORITY', 1]) # The authority value for the units
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/gis/utils/layermapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ def save(
progress:
When this keyword is set, status information will be printed giving
the number of features processed and successfully saved. By default,
progress information will pe printed every 1000 features processed,
progress information will be printed every 1000 features processed,
however, this default may be overridden by setting this keyword with
an integer for the desired interval.
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/sessions/backends/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ async def asave(self, must_create=False):
obj = await self.acreate_model_instance(data)
using = router.db_for_write(self.model, instance=obj)
try:
# This code MOST run in a transaction, so it requires
# This code MUST run in a transaction, so it requires
# @sync_to_async wrapping until transaction.atomic() supports
# async.
@sync_to_async
Expand Down
2 changes: 1 addition & 1 deletion django/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class EmptyResultSet(Exception):


class FullResultSet(Exception):
"""A database query predicate is matches everything."""
"""A database query predicate that matches everything."""

pass

Expand Down
6 changes: 3 additions & 3 deletions django/core/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,17 +513,17 @@ class DecimalValidator:
messages = {
"invalid": _("Enter a number."),
"max_digits": ngettext_lazy(
"Ensure that there are no more than %(max)s digit in total.",
"Ensure that there is no more than %(max)s digit in total.",
"Ensure that there are no more than %(max)s digits in total.",
"max",
),
"max_decimal_places": ngettext_lazy(
"Ensure that there are no more than %(max)s decimal place.",
"Ensure that there is no more than %(max)s decimal place.",
"Ensure that there are no more than %(max)s decimal places.",
"max",
),
"max_whole_digits": ngettext_lazy(
"Ensure that there are no more than %(max)s digit before the decimal "
"Ensure that there is no more than %(max)s digit before the decimal "
"point.",
"Ensure that there are no more than %(max)s digits before the decimal "
"point.",
Expand Down
2 changes: 1 addition & 1 deletion django/db/backends/ddl_references.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
Helpers to manipulate deferred DDL statements that might need to be adjusted or
discarded within when executing a migration.
discarded when executing a migration.
"""

from copy import deepcopy
Expand Down
2 changes: 1 addition & 1 deletion django/db/backends/mysql/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def date_extract_sql(self, lookup_type, sql, params):
# EXTRACT returns 1-53 based on ISO-8601 for the week number.
lookup_type = lookup_type.upper()
if not self._extract_format_re.fullmatch(lookup_type):
raise ValueError(f"Invalid loookup type: {lookup_type!r}")
raise ValueError(f"Invalid lookup type: {lookup_type!r}")
return f"EXTRACT({lookup_type} FROM {sql})", params

def date_trunc_sql(self, lookup_type, sql, params, tzname=None):
Expand Down
2 changes: 1 addition & 1 deletion django/db/backends/oracle/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ def _output_type_handler(cursor, name, defaultType, length, precision, scale):
arraysize=cursor.arraysize,
outconverter=outconverter,
)
# oracledb 2.0.0+ returns NLOB columns with IS JSON constraints as
# oracledb 2.0.0+ returns NCLOB columns with IS JSON constraints as
# dicts. Use a no-op converter to avoid this.
elif defaultType == Database.DB_TYPE_NCLOB:
return cursor.var(Database.DB_TYPE_NCLOB, arraysize=cursor.arraysize)
Expand Down
4 changes: 2 additions & 2 deletions django/db/backends/oracle/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def date_extract_sql(self, lookup_type, sql, params):
else:
lookup_type = lookup_type.upper()
if not self._extract_format_re.fullmatch(lookup_type):
raise ValueError(f"Invalid loookup type: {lookup_type!r}")
raise ValueError(f"Invalid lookup type: {lookup_type!r}")
# https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/EXTRACT-datetime.html
return f"EXTRACT({lookup_type} FROM {sql})", params
return extract_sql, (*params, extract_param)
Expand Down Expand Up @@ -198,7 +198,7 @@ def time_extract_sql(self, lookup_type, sql, params):
def time_trunc_sql(self, lookup_type, sql, params, tzname=None):
# The implementation is similar to `datetime_trunc_sql` as both
# `DateTimeField` and `TimeField` are stored as TIMESTAMP where
# the date part of the later is ignored.
# the date part of the latter is ignored.
sql, params = self._convert_sql_to_tz(sql, params, tzname)
trunc_param = None
if lookup_type == "hour":
Expand Down
2 changes: 1 addition & 1 deletion django/db/backends/postgresql/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def pool(self):
**pool_options,
)
# setdefault() ensures that multiple threads don't set this in
# parallel. Since we do not open the pool during it's init above,
# parallel. Since we do not open the pool during its init above,
# this means that at worst during startup multiple threads generate
# pool objects and the first to set it wins.
self._connection_pools.setdefault(self.alias, pool)
Expand Down
2 changes: 1 addition & 1 deletion django/db/backends/postgresql/psycopg_any.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def mogrify(sql, params, connection):
# Adapters.
class BaseTzLoader(adapt.Loader):
"""
Load a PostgreSQL timestamptz using the a specific timezone.
Load a PostgreSQL timestamptz using a specific timezone.
The timezone can be None too, in which case it will be chopped.
"""

Expand Down
2 changes: 1 addition & 1 deletion django/db/backends/sqlite3/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ def is_self_referential(f):
# Delete the old table to make way for the new
self.delete_model(model, handle_autom2m=False)

# Rename the new table to take way for the old
# Rename the new table to make way for the old
self.alter_db_table(
new_model,
new_model._meta.db_table,
Expand Down
2 changes: 1 addition & 1 deletion django/db/migrations/recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def migration_qs(self):
def has_table(self):
"""Return True if the django_migrations table exists."""
# If the migrations table has already been confirmed to exist, don't
# recheck it's existence.
# recheck its existence.
if self._has_table:
return True
# It hasn't been confirmed to exist, recheck.
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1593,7 +1593,7 @@ def _perform_date_checks(self, date_checks):
for model_class, lookup_type, field, unique_for in date_checks:
lookup_kwargs = {}
# there's a ticket to add a date lookup, we can remove this special
# case if that makes it's way in
# case if that makes its way in
date = getattr(self, unique_for)
if date is None:
continue
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def contribute_to_class(self, cls, name):
if self.verbose_name_plural is None:
self.verbose_name_plural = format_lazy("{}s", self.verbose_name)

# order_with_respect_and ordering are mutually exclusive.
# order_with_respect_to and ordering are mutually exclusive.
self._ordering_clash = bool(self.ordering and self.order_with_respect_to)

# Any leftover attributes must be invalid.
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/sql/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ def _order_by_pairs(self):
else:
if self.query.combinator and self.select:
# Don't use the first model's field because other
# combinated queries might define it differently.
# combined queries might define it differently.
yield OrderBy(F(col), descending=descending), False
else:
# 'col' is of the form 'field' or 'field1__field2' or
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/sql/datastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def __init__(
)
# Along which field (or ForeignObjectRel in the reverse join case)
self.join_field = join_field
# Is this join nullabled?
# Is this join nullable?
self.nullable = nullable
self.filtered_relation = filtered_relation

Expand Down
2 changes: 1 addition & 1 deletion django/db/models/sql/where.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def split_having_qualify(self, negated=False, must_group_by=False):
and self.contains_aggregate
and not self.contains_over_clause
):
# It's must cheaper to short-circuit and stash everything in the
# It's much cheaper to short-circuit and stash everything in the
# HAVING clause than split children if possible.
return None, self, None
where_parts = []
Expand Down
2 changes: 1 addition & 1 deletion django/forms/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,7 @@ def clean(self, value):
return None
# if there is no value act as we did before.
return self.parent_instance
# ensure the we compare the values as equal types.
# ensure we compare the values as equal types.
if self.to_field:
orig = getattr(self.parent_instance, self.to_field)
else:
Expand Down
2 changes: 1 addition & 1 deletion django/http/multipartparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ def _update_unget_history(self, num_bytes):
"""
Update the unget history as a sanity check to see if we've pushed
back the same number of bytes in one chunk. If we keep ungetting the
same number of bytes many times (here, 50), we're mostly likely in an
same number of bytes many times (here, 50), we're most likely in an
infinite loop of some sort. This is usually caused by a
maliciously-malformed MIME request.
"""
Expand Down
2 changes: 1 addition & 1 deletion django/template/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def flatten(self):

def __eq__(self, other):
"""
Compare two contexts by comparing theirs 'dicts' attributes.
Compare two contexts by comparing their 'dicts' attributes.
"""
if not isinstance(other, BaseContext):
return NotImplemented
Expand Down
2 changes: 1 addition & 1 deletion django/templatetags/tz.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def do_timezone(value, arg):
if timezone.is_naive(value):
default_timezone = timezone.get_default_timezone()
value = timezone.make_aware(value, default_timezone)
# Filters must never raise exceptionsm, so catch everything.
# Filters must never raise exceptions, so catch everything.
except Exception:
return ""

Expand Down
6 changes: 3 additions & 3 deletions django/utils/autoreload.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ def _watch_root(self, root):
# changes, however, as this is currently an internal API, no files
# will be being watched outside of sys.path. Fixing this by checking
# inside watch_glob() and watch_dir() is expensive, instead this could
# could fall back to the StatReloader if this case is detected? For
# fall back to the StatReloader if this case is detected? For
# now, watching its parent, if possible, is sufficient.
if not root.exists():
if not root.parent.exists():
Expand Down Expand Up @@ -531,8 +531,8 @@ def _watch_glob(self, directory, patterns):
"""
Watch a directory with a specific glob. If the directory doesn't yet
exist, attempt to watch the parent directory and amend the patterns to
include this. It's important this method isn't called more than one per
directory when updating all subscriptions. Subsequent calls will
include this. It's important this method isn't called more than once
per directory when updating all subscriptions. Subsequent calls will
overwrite the named subscription, so it must include all possible glob
expressions.
"""
Expand Down
2 changes: 1 addition & 1 deletion django/utils/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def filepath_to_uri(path):
def get_system_encoding():
"""
The encoding for the character type functions. Fallback to 'ascii' if the
#encoding is unsupported by Python or could not be determined. See tickets
encoding is unsupported by Python or could not be determined. See tickets
#10335 and #5846.
"""
try:
Expand Down
2 changes: 1 addition & 1 deletion django/utils/regex_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def normalize(pattern):
raise ValueError(
"Non-reversible reg-exp portion: '(?P%s'" % ch
)
# We are in a named capturing group. Extra the name and
# This is a named capturing group. Extract the name and
# then skip to the end.
if ch == "<":
terminal_char = ">"
Expand Down
2 changes: 1 addition & 1 deletion django/utils/translation/trans_real.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ def npgettext(context, singular, plural, number):

def all_locale_paths():
"""
Return a list of paths to user-provides languages files.
Return a list of paths to user-provided language files.
"""
globalpath = os.path.join(
os.path.dirname(sys.modules[settings.__module__].__file__), "locale"
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.append(abspath(join(dirname(__file__), "_ext")))

# Use the module to GitHub url resolver, but import it after the _ext directoy
# Use the module to GitHub url resolver, but import it after the _ext directory
# it lives in has been added to sys.path.
import github_links # NOQA

Expand Down
Loading
Loading