Opened 5 weeks ago

Closed 5 weeks ago

Last modified 5 weeks ago

#36076 closed New feature (wontfix)

Raise a check error if null=False and default=None

Reported by: Csirmaz Bendegúz Owned by:
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Csirmaz Bendegúz Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description (last modified by Csirmaz Bendegúz)

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.

Change History (6)

comment:1 by Csirmaz Bendegúz, 5 weeks ago

Description: modified (diff)
Easy pickings: set
Owner: Csirmaz Bendegúz removed
Status: assignednew

I think this is an easy win if someone else wants to work on it?

comment:2 by Sarah Boyce, 5 weeks ago

For context, this has come up from this PR discussion

comment:3 by Jacob Walls, 5 weeks ago

Resolution: wontfix
Status: newclosed

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 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.

comment:4 by Csirmaz Bendegúz, 5 weeks ago

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 system check to Field.check to prevent it? I'm sorry maybe I'm missing something

comment:5 by Jacob Walls, 5 weeks ago

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.

comment:6 by Jacob Walls, 5 weeks ago

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 rejected albeit without much discussion.)

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