[Django] #36076: Raise a check error if null=False and default=None

10 views
Skip to first unread message

Django

unread,
Jan 9, 2025, 6:31:23 AMJan 9
to django-...@googlegroups.com
#36076: Raise a check error if null=False and default=None
-------------------------------------+-------------------------------------
Reporter: Csirmaz | Owner: Csirmaz Bendegúz
Bendegúz |
Type: New | Status: assigned
feature |
Component: Database | Version: dev
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
If a field has `null=False` Django shouldn't allow setting `default=None`.

{{{
class Model(models.Model):
text = models.TextField(default=None)
}}}

This will raise an `IntegrityError` on create.
It could be prevented with a system check.
Same applies to `db_default`.
--
Ticket URL: <https://code.djangoproject.com/ticket/36076>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jan 9, 2025, 6:33:35 AMJan 9
to django-...@googlegroups.com
#36076: Raise a check error if null=False and default=None
-------------------------------------+-------------------------------------
Reporter: Csirmaz Bendegúz | Owner: (none)
Type: New feature | Status: new
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Csirmaz Bendegúz):

* easy: 0 => 1
* owner: Csirmaz Bendegúz => (none)
* status: assigned => new


Old description:

> If a field has `null=False` Django shouldn't allow setting
> `default=None`.
>
> {{{
> class Model(models.Model):
> text = models.TextField(default=None)
> }}}
>
> This will raise an `IntegrityError` on create.
> It could be prevented with a system check.
> Same applies to `db_default`.

New description:

If a field has `null=False` Django shouldn't allow setting `default=None`
or `db_default=None`.

{{{
class Model(models.Model):
text = models.TextField(default=None)
}}}

This will raise an `IntegrityError` on create.
It could be prevented with a system check.
Same applies to `db_default`.

--
Comment:

I think this is an easy win if someone else wants to work on it?
--
Ticket URL: <https://code.djangoproject.com/ticket/36076#comment:1>

Django

unread,
Jan 9, 2025, 6:46:58 AMJan 9
to django-...@googlegroups.com
#36076: Raise a check error if null=False and default=None
-------------------------------------+-------------------------------------
Reporter: Csirmaz Bendegúz | Owner: (none)
Type: New feature | Status: new
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Sarah Boyce):

For context, this has come up from
[https://github.com/django/django/pull/19008#discussion_r1908209970 this
PR discussion]
--
Ticket URL: <https://code.djangoproject.com/ticket/36076#comment:2>

Django

unread,
Jan 9, 2025, 8:45:39 AMJan 9
to django-...@googlegroups.com
#36076: Raise a check error if null=False and default=None
-------------------------------------+-------------------------------------
Reporter: Csirmaz Bendegúz | Owner: (none)
Type: New feature | Status: closed
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* resolution: => wontfix
* status: new => closed

Comment:

I'm not sure how we could do this, since requiring python-level defaults
on model fields would break the pattern of defaulting fields empty but
[https://docs.djangoproject.com/en/dev/ref/models/fields/#blank supplying
missing values] during validation.

More thorough discussion here:
https://groups.google.com/g/django-developers/c/GlYM25fdRnA/m/wAimd4QPAwAJ

Happy to discuss further on the forum where more folks can contribute
ideas.
--
Ticket URL: <https://code.djangoproject.com/ticket/36076#comment:3>

Django

unread,
Jan 9, 2025, 9:13:34 AMJan 9
to django-...@googlegroups.com
#36076: Raise a check error if null=False and default=None
-------------------------------------+-------------------------------------
Reporter: Csirmaz Bendegúz | Owner: (none)
Type: New feature | Status: closed
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Csirmaz Bendegúz):

I'm not sure what you mean by requiring python-level defaults? To have
`default=None` on a non-nullable field is a misconfiguration and we can
easily add a [https://docs.djangoproject.com/en/5.1/topics/checks/ system
check] to `Field.check` to prevent it? I'm sorry maybe I'm missing
something
--
Ticket URL: <https://code.djangoproject.com/ticket/36076#comment:4>

Django

unread,
Jan 9, 2025, 9:38:42 AMJan 9
to django-...@googlegroups.com
#36076: Raise a check error if null=False and default=None
-------------------------------------+-------------------------------------
Reporter: Csirmaz Bendegúz | Owner: (none)
Type: New feature | Status: closed
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Jacob Walls):

My point was that we if we permit `blank=True` for non-nullable fields
(see linked discussions) then we should treat `default=None` no
differently. It doesn't seem like a misconfiguration to me. The `default`
kwarg on model fields is only one of several ways of accepting values
before saving a non-nullable field to the database--we shouldn't force
people to choose model field defaults as a way of supplying missing
values.

If part of the proposal was to use a `NOT_PROVIDED` sentinel for the
default value of `default=` so that explicitly providing
`Field(default=None)` can be distinguished from `Field()` and flagged,
then that's a different story, but I'm not sure it's worth it and would
still break existing code.
--
Ticket URL: <https://code.djangoproject.com/ticket/36076#comment:5>

Django

unread,
Jan 10, 2025, 12:02:42 AMJan 10
to django-...@googlegroups.com
#36076: Raise a check error if null=False and default=None
-------------------------------------+-------------------------------------
Reporter: Csirmaz Bendegúz | Owner: (none)
Type: New feature | Status: closed
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Jacob Walls):

My apologies for confusing things a little bit here.

> If part of the proposal was to use a NOT_PROVIDED sentinel for the
default value of default=

Well that's exactly what Django does, don't know why I seemed to think
this morning that wasn't the case 🤦‍ ️

With that confession out of the way, it still strikes me that this should
be sounded out on the forum to move it forward. To me, requiring `Field()`
over `Field(default=None)` feels like a code-style convention for a
linter, not a misconfiguration for a system check. Asking developers to
prefer one over the other requires knowing that there is a difference,
namely the `NOT_PROVIDED` sentinel, which we would also need to document.
I think teaching this to users could be avoided.

(I also noticed while grepping test models for `default=None` that was
discussed in the context of a check on the postgres `ArrayField` and was
[https://github.com/django/django/pull/8930#discussion_r134115086
rejected] albeit without much discussion.)
--
Ticket URL: <https://code.djangoproject.com/ticket/36076#comment:6>
Reply all
Reply to author
Forward
0 new messages