Opened 6 years ago

Closed 6 years ago

#27197 closed Cleanup/optimization (wontfix)

Document how blank=True affects the migrations questioner

Reported by: Jarek Glowacki Owned by: nobody
Component: Documentation Version: dev
Severity: Normal Keywords: CharField blank emptystring
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


As a result of #23405, we now have hidden behaviour for the blank argument. I support that ticket, but I'd like to debate its use of blank.

Recapping that ticket:
If a CharField (or TextField) is added to an existing model, we can set blank=True on it to give all existing rows in the database an empty string. If we don't (assuming we don't set null=True either), we'll be forced to either set default or pick a value to populate existing rows interactively.

According to the docs, blank is supposed to be used for validation only (frontend implied). This was noted here in the past, but ultimately dismissed.

It doesn't make sense to check blank to decide the fate of existing rows in the db if new rows still default to emptystring regardless of what blank is. If default is not provided, existing rows should be assigned emptystring.

1) If the aim is to draw a parallel with the behaviour of null=True for FKs, then there should be a new argument, say, empty=True, to denote backend validation for emptystrings. blank already has its own meaning and it has nothing to do with the db.
2) If the aim is to try to be helpful to less confident Django users by entering interactive mode if they've forgotten to set default, then the undocumented behaviour of blank does this no justice and can just lead to more confusion.
3) If the aim is to mimic South then this aim is no longer relevant as South has been gone for several versions now, and Django migrations already behave quite differently to South in many respects. I've never actually used south, but I also suspect its definition of blank was not the same as Django's.
4) If the aim is to keep things simple since blank=True comes hand in hand with emptystring in most cases, then this is a poor aim, as there should be a distinction between backend and frontend validation (see first point). Further, blank is not tied solely to string fields, but to all fields.
5) There should be no difference in population of existing rows and new rows. Otherwise we could make the same argument about default affecting existing rows when it should only affect new rows (or vice versa).
6) I hate that I have to set blank=True when adding a new CharField, even though it only matters to the AddField migration and is completely irrelevant beyond that. Further, my model is left with this cruft for all eternity, lest I remove it and face the interpreter at the next migrate call.

So, options:

  • [Suggested] Do not check the value of blank. If null=False and default is unset, set all CharFields and TextFields to emptystring. It's hardly painful to write a migration to populate these later if this was not the user's intention. With this we solidify blank as purely a frontend validator. For string-type fields it decides whether or not emptystring is allowed; for related fields it determines whether or not nulls are allowed; etc .. (empty dict for JSONField? idk, haven't checked).
  • [Bare minimum] Mention in docs that blank has this magical secondary functionality.
  • [Meh] Revert #23405 and force default to always be set in the absence of null=True. I don't see any merit to this, besides perhaps bringing overall consistency in line with BooleanField.

Sorry about the long rant, hopefully it makes me come across as passionate about the project rather than fixated on tiny nits. :3

Change History (5)

comment:1 Changed 6 years ago by Tim Graham

Component: MigrationsDocumentation
Summary: Document hidden functionality of 'blank' on a CharField or remove it.Document how blank=True affects the migrations questioner

If you want to revisit the original design decision, you should raise the idea on the DevelopersMailingList. I don't think any of the behavior of the migrations question is documented and I'm not sure it needs to be, hence, absent other opinions, I lean toward closing this ticket as wontfix.

Your real complain seems to be that the prompt for a default happens at all (whether blank=True or blank=False). I don't see why you don't omit blank=True and enter an empty string when prompted for a "one-off value" by the questioner?

comment:2 Changed 6 years ago by Jarek Glowacki

Ah, sorry, I thought opening a ticket was the correct course of action. I'll ask there.

The questioner quickly loses feasibility when there are many databases to run the migrations on. Hinders automation.

comment:3 Changed 6 years ago by Tim Graham

The questioner happens when generating a migration, not when running it.

comment:4 Changed 6 years ago by Jarek Glowacki

Oh crap, you're right. My use case is a non-issue here then.

I might still open a django-dev mailing topic to complain about what I feel is a misuse of blank, but suddenly this all seems much less problematic than I'd initially thought.

Thanks for clarifying and sorry to waste your time!

comment:5 Changed 6 years ago by Tim Graham

Resolution: wontfix
Status: newclosed

Discussion to continue on django-developers.

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