Currently, db_default
has no effect on model forms. I was mistakenly under the assumption that it would behave somewhat similarly to default
(if default
is not set in addition to db_default
).
There are 3 behaviours that I think we should be considered for either alteration or clarification in the docs:
1. Supplying an initial value
When default
is set, the model form’s field gets it’s initial
set to the default. This makes sense for default
but should it set it for db_default
if we have simple scalar values like Value("asdf")
?
I’m not a big fan of too much magic so I’d probably lean towards no - and document this saying that if you want the default value to show on the form then it would need to be declared on the form or via default
if that makes sense to set that on top of db_default
.
2. Setting the field’s required flag
Currently a non-null field with db_default
set has required=True
. This can be solved with blank=True
on the model field but perhaps again the model form field generation could be changed? If not then some doc updates to explain this might be nice.
3. Setting the form field’s empty value
When a form is submitted, the form field’s empty value is passed to the ORM and db_default
is never used. I found that if setting a field’s empty_value=DatabaseDefault()
then this allows delegating the value to db_default
.
Currently users need to manually create a model form and set the empty_value
but this isn’t an obvious solution because DatabaseDefault
is currently undocumented.
Since this is a non-obvious, I strongly recommend that either DatabaseDefault
is documented; or we could add this small change to Django in db.models.fields.Field.formfield()
:
def formfield(self, …):
…
if self.db_default is not NOT_PROVIDED:
defaults["empty_value"] = DatabaseDefault()
…
Another option may be to include DatabaseDefault
in the field’s initial upon rendering but this is a non-trivial approach as we’d need to manage it (eg not rendering it) and additionally Field.has_default()
vs Field.get_default()
both deal with db_default
differently.