#35671: Field.null=False on string-based fields behaves inconsistently with the
typical usage of Field.null.
-------------------------------------+-------------------------------------
Reporter: Clifford Gama | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: 5.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: Field.null; | Triage Stage:
IntegrityError; | Unreviewed
NotNullConstraint; Field.default |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Clifford Gama:
Old description:
> When `Field.null=False` and `Field.default` is not set for string-based
> fields—such as `CharField`, `TextField`, and `SlugField`—`Field.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 `IntegrityError`s 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.
New description:
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 `SlugField`—`Field.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 `IntegrityError`s 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.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/35671#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/01070191481f6092-2de6309d-e93c-4eba-97f8-8b3035bc71a4-000000%40eu-central-1.amazonses.com.