craigds/django-typed-models

Fields with default values shouldn't need to be nullable

Closed this issue · 7 comments

vosi commented
class BaseModel(TypedModel):
    some_fields = ...
class MyModel(BaseModel):
    field = models.BooleanField(default=False)

result

SystemCheckError: System check identified some issues:

ERRORS:
app.BaseModel.field: (fields.E110) BooleanFields do not accept null values.
	HINT: Use a NullBooleanField instead.

Interesting.

typedmodels forces all fields defined on subclasses to null=True, since they're not defined for all possible types.

(aside: I wasn't aware that django had a NullBooleanField, I wonder why that's there? I'd guess something to do with HTML widgets - you need a dropdown for a three-state thing instead of a checkbox.)

I don't think there's a reasonable thing that typedmodels can do here. If it magically changed your field into a NullBooleanField it'd break things that you might not expect to break, like form field types etc.

So probably the only thing we can do to improve this is add it to the docs?

vosi commented

or just skip processing boolean fields

Can't just skip it - the field has to be nullable, or you wouldn't be able to insert into the table from another BaseModel subclass. So I think there'd be two possible solutions:

  • force the caller to decide how it behaves. You can either add it to BaseModel and set a true/false default value, or change it to NullBooleanField
  • typedmodels could do some nasty magic, like forcing the db column to nullable even though the field isn't nullable. This would require messing with migrations in a way I'm not even sure is possible.

I'm definitely -1 on the latter. The right solution is to doc the limitation and make the user make the call.

vosi commented

my field has default, it doesn have to be nullable

good point.

makes perfect sense that if a default is specified, we don't need to make it nullable. I'll do that.

The implicit null=True bothers me too - I'll change it at the same time to not do that in a future version (and warn for now). Ticketed that as #39

Fixed in ea2efb4