Opened 4 months ago

Closed 4 months ago

#35671 closed Cleanup/optimization (fixed)

Clarify behavior for Field.null=False on string-based fields

Reported by: Clifford Gama Owned by: Clifford Gama
Component: Database layer (models, ORM) Version: 5.1
Severity: Normal Keywords: Field.null; IntegrityError; NotNullConstraint; Field.default
Cc: Clifford Gama 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 (last modified by Clifford Gama)

My concern is with the usage of Field.null=False, which differs from its expected practical application, rather than just its technical function.

When Field.null=False and Field.default is not set for string-based fields—such as CharField, TextField, and SlugFieldField.null does not raise the expected IntegrityError: NOT NULL constraint failed when a value is not provided for the field.

Django saves empty strings for these fields, and since the database does not (always?) interpret an empty string as NULL, they are accepted without raising the IntegrityError. This behavior is not clearly documented and is inconsistent with the typical usage of Field.null as a NOT NULL constraint.

The [documentation](https://docs.djangoproject.com/en/5.1/ref/models/fields/#django.db.models.Field.null) on Field.null specifies:

Avoid using null on string-based fields such as CharField and TextField. If a string-based field has null=True, that means it has two possible values for “no data”: NULL and the empty string. In most cases, it’s redundant to have two possible values for “no data;” the Django convention is to use the empty string, not NULL.

What is not specified here or in the documentation for Field.default is that Django effectively sets the empty string as the default for these string-based fields when none is provided. If you wish to truly disallow empty values for those fields, you need to set Field.default=None and null=False.

Since Django relies on the database to raise IntegrityErrors when a required field is not provided, it is inconsistent that Django does not treat the empty string as “no data” (i.e., NULL) in this context or that they use the empty string as “no data” when the database will interpret it as actual data.

The issue is particularly evident when a model instance is created using the model Manager's create() and get_or_create() methods or by direct instantiation.

Change History (10)

comment:1 by Clifford Gama, 4 months ago

Description: modified (diff)

comment:2 by Sarah Boyce, 4 months ago

Summary: Field.null=False on string-based fields behaves inconsistently with the typical usage of Field.null.Document how to disallow blank values in Char/TextFields
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

I don't think we can change the behavior here as this would be a breaking change and I think it makes sense that given a field which cannot be null, but can be a blank string, without a default set, it defaults to a blank string

But I agree that this is not clear in the docs and we can make an update there

Note, this is about how given a model:

class StringModel(Model):
    field = models.CharField(blank=False, null=False)

the value for StringModel().field is "", which is determined by the property Field._get_default

comment:3 by Clifford Gama, 4 months ago

Hi Sarah!

Thank you for accepting this ticket and for clarifying, in the description, what needs to be done.

comment:4 by Clifford Gama, 4 months ago

Owner: set to Clifford Gama
Status: newassigned

comment:5 by Clifford Gama, 4 months ago

I have made the relevant additions in the documentation. You can view my progress on the branch here: [ticket_35671](https://github.com/cliff688/django/tree/ticket_35671)

comment:6 by Clifford Gama, 4 months ago

Has patch: set

comment:7 by Sarah Boyce, 4 months ago

Patch needs improvement: set

comment:8 by Sarah Boyce, 4 months ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:9 by Sarah Boyce, 4 months ago

Summary: Document how to disallow blank values in Char/TextFieldsClarify behavior for Field.null=False on string-based fields

comment:10 by Sarah Boyce <42296566+sarahboyce@…>, 4 months ago

Resolution: fixed
Status: assignedclosed

In ca131898:

Fixed #35671 -- Clarified string-based fields behavior when null=False.

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