Skip to content
7 changes: 5 additions & 2 deletions django/core/management/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,11 @@ def __init__(
):
self.missing_args_message = missing_args_message
self.called_from_command_line = called_from_command_line
if PY314 and not PY315:
kwargs.setdefault("suggest_on_error", True)
if PY314:
if not PY315:
kwargs.setdefault("suggest_on_error", True)
if os.environ.get("DJANGO_COLORS") == "nocolor" or "--no-color" in sys.argv:
kwargs.setdefault("color", False)
super().__init__(**kwargs)

def parse_args(self, args=None, namespace=None):
Expand Down
42 changes: 33 additions & 9 deletions django/core/serializers/xml_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ def handle_fk_field(self, obj, field):
# Iterable natural keys are rolled out as subelements
for key_value in natural_key_value:
self.xml.startElement("natural", {})
self.xml.characters(str(key_value))
if key_value is None:
self.xml.addQuickElement("None")
else:
self.xml.characters(str(key_value))
self.xml.endElement("natural")
else:
self.xml.characters(str(related_att))
Expand All @@ -160,7 +163,10 @@ def handle_m2m(value):
self.xml.startElement("object", {})
for key_value in natural:
self.xml.startElement("natural", {})
self.xml.characters(str(key_value))
if key_value is None:
self.xml.addQuickElement("None")
else:
self.xml.characters(str(key_value))
self.xml.endElement("natural")
self.xml.endElement("object")
else:
Expand Down Expand Up @@ -279,7 +285,11 @@ def _handle_object(self, node):
if value == base.DEFER_FIELD:
deferred_fields[field] = [
[
getInnerText(nat_node).strip()
(
None
if nat_node.getElementsByTagName("None")
else getInnerText(nat_node).strip()
)
for nat_node in obj_node.getElementsByTagName("natural")
]
for obj_node in field_node.getElementsByTagName("object")
Expand All @@ -292,7 +302,11 @@ def _handle_object(self, node):
value = self._handle_fk_field_node(field_node, field)
if value == base.DEFER_FIELD:
deferred_fields[field] = [
getInnerText(k).strip()
(
None
if k.getElementsByTagName("None")
else getInnerText(k).strip()
)
for k in field_node.getElementsByTagName("natural")
]
else:
Expand All @@ -317,16 +331,21 @@ def _handle_fk_field_node(self, node, field):
Handle a <field> node for a ForeignKey
"""
# Check if there is a child node named 'None', returning None if so.
if node.getElementsByTagName("None"):
natural_keys = node.getElementsByTagName("natural")
if node.getElementsByTagName("None") and not natural_keys:
return None
else:
model = field.remote_field.model
if hasattr(model._default_manager, "get_by_natural_key"):
keys = node.getElementsByTagName("natural")
if keys:
if natural_keys:
# If there are 'natural' subelements, it must be a natural
# key
field_value = [getInnerText(k).strip() for k in keys]
field_value = []
for k in natural_keys:
if k.getElementsByTagName("None"):
field_value.append(None)
else:
field_value.append(getInnerText(k).strip())
try:
obj = model._default_manager.db_manager(
self.db
Expand Down Expand Up @@ -367,7 +386,12 @@ def m2m_convert(n):
if keys:
# If there are 'natural' subelements, it must be a natural
# key
field_value = [getInnerText(k).strip() for k in keys]
field_value = []
for k in keys:
if k.getElementsByTagName("None"):
field_value.append(None)
else:
field_value.append(getInnerText(k).strip())
obj_pk = (
default_manager.db_manager(self.db)
.get_by_natural_key(*field_value)
Expand Down
14 changes: 13 additions & 1 deletion django/db/models/fields/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,19 @@ def as_oracle(self, compiler, connection):
class KeyTransformIExact(
CaseInsensitiveMixin, KeyTransformTextLookupMixin, lookups.IExact
):
pass
can_use_none_as_rhs = True

def as_sql(self, compiler, connection):
if self.rhs is None:
# Interpret __iexact=None on KeyTextTransform as __exact=None on
# KeyTransform.
keytransform = KeyTransform(self.lhs.key_name, self.lhs.lhs)
exact_lookup = keytransform.get_lookup("exact")(keytransform, self.rhs)
# Delegate to the backend vendor method, if it exists.
vendor = connection.vendor
as_vendor = getattr(exact_lookup, f"as_{vendor}", exact_lookup.as_sql)
return as_vendor(compiler, connection)
return super().as_sql(compiler, connection)


class KeyTransformIContains(
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/lookups.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def get_prep_lookup(self):
(
value
if hasattr(value, "resolve_expression")
else Value(value, self.lhs.output_field)
else Value(value, getattr(self.lhs, "output_field", None))
)
for value in self.rhs
]
Expand Down
37 changes: 37 additions & 0 deletions docs/internals/contributing/writing-documentation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,43 @@ documentation:
* Use :rst:role:`:cve:<cve>` to reference a Common Vulnerabilities and
Exposures (CVE) identifier. For example, use ``:cve:`2019-14232```.

* When documenting Python objects (classes, methods, attributes, etc.) using
`Sphinx directives`__ such as ``.. class::``, ``.. method::``, and
``.. attribute::``, all content must be properly indented to ensure correct
rendering and to support features like automatic table of contents
generation.

Follow these rules:

* The directive itself remains flush with the left margin (no indentation).
* All descriptive text under the directive must be indented by 4 spaces.
* Multi-line descriptions must keep the same indentation level.
* Nested directives (for example, methods inside a class) require an
additional 4 spaces of indentation to maintain hierarchy.
* Field lists (such as ``:param:``, ``:returns:``, etc.) must align with the
directive's content level.

Example:

.. code-block:: rst

.. class:: MyClass

A brief description of the class.

.. method:: my_method(arg1, arg2)

Method description.

:param arg1: Description of the first parameter
:param arg2: Description of the second parameter

.. attribute:: my_attribute

Attribute description.

__ https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html

Django-specific markup
======================

Expand Down
72 changes: 36 additions & 36 deletions docs/ref/checks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,42 @@ API reference

.. class:: CheckMessage(level, msg, hint=None, obj=None, id=None)

The warnings and errors raised by system checks must be instances of
``CheckMessage``. An instance encapsulates a single reportable error or
warning. It also provides context and hints applicable to the message, and a
unique identifier that is used for filtering purposes.

Constructor arguments are:

``level``
The severity of the message. Use one of the predefined values: ``DEBUG``,
``INFO``, ``WARNING``, ``ERROR``, ``CRITICAL``. If the level is greater or
equal to ``ERROR``, then Django will prevent management commands from
executing. Messages with level lower than ``ERROR`` (i.e. warnings) are
reported to the console, but can be silenced.

``msg``
A short (less than 80 characters) string describing the problem. The string
should *not* contain newlines.

``hint``
A single-line string providing a hint for fixing the problem. If no hint
can be provided, or the hint is self-evident from the error message, the
hint can be omitted, or a value of ``None`` can be used.

``obj``
Optional. An object providing context for the message (for example, the
model where the problem was discovered). The object should be a model,
field, or manager or any other object that defines a ``__str__()`` method.
The method is used while reporting all messages and its result precedes the
message.

``id``
Optional string. A unique identifier for the issue. Identifiers should
follow the pattern ``applabel.X001``, where ``X`` is one of the letters
``CEWID``, indicating the message severity (``C`` for criticals, ``E`` for
errors and so). The number can be allocated by the application, but should
be unique within that application.
The warnings and errors raised by system checks must be instances of
``CheckMessage``. An instance encapsulates a single reportable error or
warning. It also provides context and hints applicable to the message, and
a unique identifier that is used for filtering purposes.

Constructor arguments are:

``level``
The severity of the message. Use one of the predefined values: ``DEBUG``
, ``INFO``, ``WARNING``, ``ERROR``, ``CRITICAL``. If the level is
greater or equal to ``ERROR``, then Django will prevent management
commands from executing. Messages with level lower than ``ERROR``
(i.e. warnings) are reported to the console, but can be silenced.

``msg``
A short (less than 80 characters) string describing the problem. The
string should *not* contain newlines.

``hint``
A single-line string providing a hint for fixing the problem. If no hint
can be provided, or the hint is self-evident from the error message, the
hint can be omitted, or a value of ``None`` can be used.

``obj``
Optional. An object providing context for the message (for example, the
model where the problem was discovered). The object should be a model,
field, or manager or any other object that defines a ``__str__()``
method. The method is used while reporting all messages and its result
precedes the message.

``id``
Optional string. A unique identifier for the issue. Identifiers should
follow the pattern ``applabel.X001``, where ``X`` is one of the letters
``CEWID``, indicating the message severity (``C`` for criticals, ``E``
for errors and so). The number can be allocated by the application, but
should be unique within that application.

There are subclasses to make creating messages with common levels easier. When
using them you can omit the ``level`` argument because it is implied by the
Expand Down
Loading