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: 0 additions & 16 deletions django/db/models/fields/generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ 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 @@ -83,7 +82,6 @@ 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 @@ -190,20 +188,6 @@ 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
3 changes: 2 additions & 1 deletion docs/ref/checks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ 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.W225**: ``null`` has no effect on ``GeneratedField``. *This check
is removed in Django 6.1.2.*
* **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: 0 additions & 3 deletions docs/ref/models/fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1366,9 +1366,6 @@ materialized view.
.. _PostgreSQL: https://www.postgresql.org/docs/current/ddl-generated-columns.html
.. _SQLite: https://www.sqlite.org/gencol.html#limitations

:attr:`~Field.null` has no effect on ``GeneratedField`` since whether the
column is nullable depends on the database and expression used.

``GenericIPAddressField``
-------------------------

Expand Down
3 changes: 3 additions & 0 deletions docs/releases/6.1.2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ Bugfixes

* Fixed a data loss issue in Django 4.0 where :ref:`network rasters
<gdal-raster-network>` were deleted by GeoDjango when closed.

* Fixed a bug in Django 6.1 where the ``fields.W225`` system check incorrectly
warned that ``null`` has no effect on ``GeneratedField`` (:ticket:`37348`).
23 changes: 0 additions & 23 deletions tests/invalid_models_tests/test_ordinary_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1510,26 +1510,3 @@ 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,
)
2 changes: 2 additions & 0 deletions tests/model_fields/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ class GeneratedModelNull(models.Model):
expression=Lower("name"),
output_field=models.CharField(max_length=10),
db_persist=True,
null=True,
)

class Meta:
Expand All @@ -667,6 +668,7 @@ class GeneratedModelNullVirtual(models.Model):
expression=Lower("name"),
output_field=models.CharField(max_length=10),
db_persist=False,
null=True,
)

class Meta:
Expand Down
9 changes: 9 additions & 0 deletions tests/model_fields/test_generatedfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,15 @@ def test_nullable(self):
with self.assertNumQueries(expected_num_queries):
self.assertEqual(m2.lower_name, "name")

def test_nullable_exclude(self):
m1 = self.nullable_model.objects.create()
m2 = self.nullable_model.objects.create(name="NaMe")
self.nullable_model.objects.create(name="Other")
self.assertSequenceEqual(
self.nullable_model.objects.exclude(lower_name="other").order_by("pk"),
[m1, m2],
)


@skipUnlessDBFeature("supports_stored_generated_columns")
class StoredGeneratedFieldTests(GeneratedFieldTestMixin, TestCase):
Expand Down
Loading