#23130: BooleanField should not override 'blank' if choices are specified
-------------------------------------+-------------------------------------
Reporter: jonash | Owner: tushar
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: | Needs documentation: 0
Has patch: 0 | Patch needs improvement: 0
Needs tests: 0 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Comment (by jonashaag):
Having given this whole business some hours' thought, I actually believe
that making a difference between BooleanField and NullBooleanField is
fundamentally wrong. I know NullBooleanField has been in Django from the
beginning and removing it/changing BooleanField is a nightmare in terms of
backwards compatibility.
Still I'd like to propose a better implementation in form of this patch:
https://gist.github.com/jonashaag/d8a9f82d88c60c103189 (This passes the
complete test suite except for a handful of minor now-outdated tests!)
In this version, BooleanField behaves much more like any other field,
simplifying both the implementation and the usage. `blank` may be used
freely as with any other field. The same applies to `null`. By default, it
renders as a checkbox and does not allow `None` (i.e. `blank=False` like
with any other field). If `blank` is set to True, it renders as choices
with an additional blank option. It also renders as choices if `choices`
is given.
`NullBooleanField` stays as a mere wrapper for `BooleanField` with
`blank=null=True`.
Here is a shortened version of the new implementation:
{{{
#!python
class BooleanField(Field):
empty_strings_allowed = False
default_error_messages = {
'invalid': _("'%(value)s' value must be either True or False."),
}
description = _("Boolean (Either True or False)")
def get_internal_type(self):
return "BooleanField"
def to_python(self, value):
if value is None:
return value
if value in (True, False):
# if value is 1 or 0 than it's equal to True or False, but we
want
# to return a true bool for semantic reasons.
return bool(value)
if value in ('t', 'True', '1'):
return True
if value in ('f', 'False', '0'):
return False
raise exceptions.ValidationError(
self.error_messages['invalid'],
code='invalid',
params={'value': value},
)
# ...
def formfield(self, **kwargs):
if self.blank or self.choices:
return super(BooleanField, self).formfield(**kwargs)
else:
# In the checkbox case, 'required' means "must be checked (=>
true)",
# which is different from the choices case ("must select some
value").
# Since we want to allow both True and False
(checked/unchecked) choices,
# set 'required' to False.
defaults = {'form_class': forms.BooleanField,
'required': False}
defaults.update(kwargs)
return super(BooleanField, self).formfield(**defaults)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/23130#comment:14>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.0a52a1a8615dd334b75205784a8f6ff1%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.