{{{
class Test(Model):
# other fields
name = CharField(max_length=20)
}}}
This field is non-nullable and has no default value. However, when an
object is created, the field gets an empty string automatically:
{{{
>>> Test().name
''
}}}
When such an object is saved, an empty string will be saved to the
database. The same happens when I call `Test.objects.create()`.
On the other hand, when I create a migration, Django asks me to provide a
default. If I omit a default value and try to execute the migration, there
will be `IntegrityError` due to the `NOT NULL` constraint.
So the question is: why does `CharField` behave differently in the
contexts of Python objects and migrations? The same goes also for
`FileField`, but not e.g. for non-nullable `IntegerField` (it won't get a
value of `0` automatically).
Changing the behaviour of objects with `CharField` would be a breaking
change, but for consistency, I think that migrations should also infer the
empty string as the default value, even when there is no `default=''` or
`blank=True`.
Possibly related: #23405.
--
Ticket URL: <https://code.djangoproject.com/ticket/32799>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* resolution: => wontfix
* component: Database layer (models, ORM) => Migrations
* type: Uncategorized => New feature
Comment:
IMO these are two different scenarios. The Django convention is to use the
empty string, not `NULL`. For a string-based field with `null=False` you
have one possible values for "no data" i.e. the empty string that's why
Django uses it when value is not provided for a non-nullable string-based
field.
Migrations asks for a default value for **existing** rows when adding a
non-nullable field to the model, and does it consistently for all type of
fields. Folks can always type `''`, it's not much of a burden.
You can start a discussion on DevelopersMailingList if you don't agree.
--
Ticket URL: <https://code.djangoproject.com/ticket/32799#comment:1>
Comment (by Adam Sołtysik):
> IMO these are two different scenarios.
The point is to make these two different scenarios work consistently, not
to break the principle of least astonishment. When model objects behave
like they have a valid default value, it's surprising that migrations
behave like there's no valid default.
> For a string-based field with null=False you have one possible values
for "no data" i.e. the empty string that's why Django uses it when value
is not provided for a non-nullable string-based field.
The same could apply to migrations. Since there's only one possible value
for "no data" for the existing rows, it's probably better to use that than
to ask for that value or crash.
> Migrations asks for a default value for existing rows when adding a non-
nullable field to the model, and does it consistently for all type of
fields.
Except for the fact that currently `blank=True` can be used with char
fields instead of a default value for the migration to work properly, even
though `blank` parameter is said
[https://docs.djangoproject.com/en/3.2/ref/models/fields/#blank in the
documentation] to matter for form validation only.
--
Ticket URL: <https://code.djangoproject.com/ticket/32799#comment:2>
Comment (by Adam Sołtysik):
> Except for the fact that currently blank=True can be used with char
fields instead of a default value for the migration to work properly, even
though blank parameter is said in the documentation to matter for form
validation only.
I've found there was already a ticket about this: #27197, and a discussion
on the mailing list: https://groups.google.com/g/django-
developers/c/upbDlFgtCHs/discussion, but without any resolution.
--
Ticket URL: <https://code.djangoproject.com/ticket/32799#comment:3>
Comment (by Mariusz Felisiak):
> The same could apply to migrations. Since there's only one possible
value for "no data" for the existing rows, it's probably better to use
that than to ask for that value or crash.
It's not the same to use the empty string for a new row and to update
**all existing** rows without asking for a value. With your proposition we
would remove an important feature from migrations and we wouldn't give
users a chance to decide on their own, which they have when creating a new
object.
Again, please start a discussion on DevelopersMailingList if you don't
agree.
--
Ticket URL: <https://code.djangoproject.com/ticket/32799#comment:4>
Comment (by Adam Sołtysik):
> With your proposition we would remove an important feature from
migrations and we wouldn't give users a chance to decide on their own
Actually, my proposition is just to make migrations use the same default
value that objects use, when there is no explicit default value given. The
questioner could still work the same if that's more consistent with other
fields. My use case was a migration edited by hand, which crashed due to
nulls, when I expected it to use empty strings.
--
Ticket URL: <https://code.djangoproject.com/ticket/32799#comment:5>