#32799 closed New feature (wontfix)
Inconsistency regarding the default value of CharField
Reported by: | Adam Sołtysik | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 3.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Let's assume I want to add a CharField
to a model:
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.
Change History (5)
comment:1 by , 3 years ago
Component: | Database layer (models, ORM) → Migrations |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
Type: | Uncategorized → New feature |
comment:2 by , 3 years ago
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 in the documentation to matter for form validation only.
comment:3 by , 3 years ago
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.
comment:4 by , 3 years ago
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.
comment:5 by , 3 years ago
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.
IMO these are two different scenarios. The Django convention is to use the empty string, not
NULL
. For a string-based field withnull=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.