Opened 4 weeks ago

Closed 3 weeks ago

Last modified 3 weeks ago

#36806 closed Cleanup/optimization (fixed)

Add system check for null kwarg in GeneratedField definition

Reported by: Dai-Tado Owned by: Nilesh Pahari
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: GeneratedField
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Summary
GeneratedField ignores null=False on MySQL - columns are always nullable

Description
When creating a GeneratedField with null=False on MySQL, the database column is always created as nullable, ignoring the null=False parameter.
Steps to Reproduce

pythonfrom django.db import models

class MyModel(models.Model):
    area = models.GeneratedField(
        .....
        null=False,  # ← Ignored
    )
  • The migration file removes null=False from GeneratedField definition
  • Even if manually added to migration file, Django doesn't apply NOT NULL constraint to database

Change History (13)

comment:1 by Dai-Tado, 4 weeks ago

Summary: GeneratedField with null=False creates nullable column on MySQL with spatial types (POINT)GeneratedField with null=False creates nullable column on MySQL

comment:2 by Dai-Tado, 4 weeks ago

If this is the expected behavior, would it be possible to include this in the official documentation?

comment:3 by Jacob Walls, 4 weeks ago

Summary: GeneratedField with null=False creates nullable column on MySQLAdd system check for null kwarg in GeneratedField definition
Type: BugCleanup/optimization

Good idea, I would be happy to accept something similar to what we have for ManyToManyField, e.g.:

  • django/db/models/fields/generated.py

    diff --git a/django/db/models/fields/generated.py b/django/db/models/fields/generated.py
    index f89269b5e6..551302475b 100644
    a b class GeneratedField(Field):  
    3030        self.expression = expression
    3131        self.output_field = output_field
    3232        self.db_persist = db_persist
     33        self.has_null = "null" in kwargs
    3334        super().__init__(**kwargs)
    3435
    3536    @cached_property
    class GeneratedField(Field):  
    8283            *super().check(**kwargs),
    8384            *self._check_supported(databases),
    8485            *self._check_persistence(databases),
     86            *self._check_ignored_options(databases),
    8587        ]
    8688        output_field_clone = self.output_field.clone()
    8789        output_field_clone.model = self.model
    class GeneratedField(Field):  
    188190                )
    189191        return errors
    190192
     193    def _check_ignored_options(self, **kwargs):
     194        warnings = []
     195
     196        if self.has_null_arg:
     197            warnings.append(
     198                checks.Warning(
     199                    "null has no effect on GeneratedField.",
     200                    obj=self,
     201                    id="fields.WXXX",
     202                )
     203            )
     204
     205        return warnings
     206
    191207    def deconstruct(self):
    192208        name, path, args, kwargs = super().deconstruct()
    193209        del kwargs["blank"]

Would you like to submit a PR and add a test? You should be able to riff on the docs & tests for ManyToMany from 011abb7d96c75f6154c15a8a0f997d8c27698679 (#19671).

comment:4 by Jacob Walls, 4 weeks ago

Keywords: GeneratedField added
Triage Stage: UnreviewedAccepted

comment:5 by Nilesh Pahari, 3 weeks ago

Owner: set to Nilesh Pahari
Status: newassigned

comment:6 by Nilesh Pahari, 3 weeks ago

Needs documentation: set
Needs tests: set

comment:7 by Nilesh Pahari, 3 weeks ago

Has patch: set

comment:9 by Jacob Walls, 3 weeks ago

Needs documentation: unset
Needs tests: unset

comment:10 by Jacob Walls, 3 weeks ago

Triage Stage: AcceptedReady for checkin
Version: 5.2dev

comment:11 by Dai-Tado, 3 weeks ago

Thank you!!

comment:12 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

Resolution: fixed
Status: assignedclosed

In 6025eab:

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.

comment:13 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

In 968f3f96:

Refs #36806 -- Removed unnecessary null=True from GeneratedField in test models.

Test coverage is preserved because the tests only verify that generated
fields can produce NULL values when the source field is nullable.

This addresses system check warnings in the test suite after
6025eab3c509b4de922117e16866bbfe0ee99aa6.

Note: See TracTickets for help on using tickets.
Back to Top