summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNilesh Kumar Pahari <nileshpahari@protonmail.com>2025-12-18 16:21:50 +0530
committerJacob Walls <jacobtylerwalls@gmail.com>2025-12-22 09:41:41 -0500
commit6025eab3c509b4de922117e16866bbfe0ee99aa6 (patch)
treed5f542be6eb02a9b12ab7fb3db93dcf54aa411de
parentafaa527c437f95ab6f8860840d83480d4d15b099 (diff)
Fixed #36806 -- Added system check for null kwarg in GeneratedField.
The null argument has no effect on GeneratedField since the nullability of the column depends on the database and expression used.
-rw-r--r--django/db/models/fields/generated.py16
-rw-r--r--docs/ref/checks.txt1
-rw-r--r--docs/ref/models/fields.txt3
-rw-r--r--tests/invalid_models_tests/test_ordinary_fields.py23
4 files changed, 43 insertions, 0 deletions
diff --git a/django/db/models/fields/generated.py b/django/db/models/fields/generated.py
index f89269b5e6..f90bc560e2 100644
--- a/django/db/models/fields/generated.py
+++ b/django/db/models/fields/generated.py
@@ -30,6 +30,7 @@ class GeneratedField(Field):
self.expression = expression
self.output_field = output_field
self.db_persist = db_persist
+ self.has_null_arg = "null" in kwargs
super().__init__(**kwargs)
@cached_property
@@ -82,6 +83,7 @@ class GeneratedField(Field):
*super().check(**kwargs),
*self._check_supported(databases),
*self._check_persistence(databases),
+ *self._check_ignored_options(databases),
]
output_field_clone = self.output_field.clone()
output_field_clone.model = self.model
@@ -188,6 +190,20 @@ class GeneratedField(Field):
)
return errors
+ def _check_ignored_options(self, databases):
+ warnings = []
+
+ if self.has_null_arg:
+ warnings.append(
+ checks.Warning(
+ "null has no effect on GeneratedField.",
+ obj=self,
+ id="fields.W225",
+ )
+ )
+
+ return warnings
+
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
del kwargs["blank"]
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index 1e56464a6f..7250df692f 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -221,6 +221,7 @@ Model fields
``GeneratedField``\s.
* **fields.E223**: ``GeneratedField.output_field`` has errors: ...
* **fields.W224**: ``GeneratedField.output_field`` has warnings: ...
+* **fields.W225**: ``null`` has no effect on ``GeneratedField``.
* **fields.E900**: ``IPAddressField`` has been removed except for support in
historical migrations.
* **fields.W900**: ``IPAddressField`` has been deprecated. Support for it
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index a87d7261a7..fe4d764ab3 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -1377,6 +1377,9 @@ materialized view.
backends that support it (SQLite, PostgreSQL, and Oracle) and marked as
deferred otherwise.
+:attr:`~Field.null` has no effect on ``GeneratedField`` since whether the
+column is nullable depends on the database and expression used.
+
``GenericIPAddressField``
-------------------------
diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py
index 04c18d7ddd..e2ce74c673 100644
--- a/tests/invalid_models_tests/test_ordinary_fields.py
+++ b/tests/invalid_models_tests/test_ordinary_fields.py
@@ -1510,3 +1510,26 @@ class GeneratedFieldTests(TestCase):
Model._meta.get_field("field").check(databases={"default"}),
expected_warnings,
)
+
+ @skipUnlessDBFeature("supports_stored_generated_columns")
+ def test_with_null_argument(self):
+ class Model(models.Model):
+ value = models.IntegerField()
+ field = models.GeneratedField(
+ expression=models.F("value") * 2,
+ output_field=models.IntegerField(),
+ db_persist=True,
+ null=True,
+ )
+
+ expected_warnings = [
+ DjangoWarning(
+ "null has no effect on GeneratedField.",
+ obj=Model._meta.get_field("field"),
+ id="fields.W225",
+ ),
+ ]
+ self.assertEqual(
+ Model._meta.get_field("field").check(databases={"default"}),
+ expected_warnings,
+ )