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
16 changes: 16 additions & 0 deletions django/db/models/fields/generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def __init__(self, *, expression, output_field, db_persist, **kwargs):
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
Expand Down Expand Up @@ -82,6 +83,7 @@ def check(self, **kwargs):
*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
Expand Down Expand Up @@ -188,6 +190,20 @@ def _check_persistence(self, databases):
)
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"]
Expand Down
1 change: 1 addition & 0 deletions docs/ref/checks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions docs/ref/models/fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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``
-------------------------

Expand Down
23 changes: 23 additions & 0 deletions tests/invalid_models_tests/test_ordinary_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1510,3 +1510,26 @@ class Model(models.Model):
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,
)