diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index 633a26b67ae..7cf75bcd0d4 100644 --- a/django/contrib/admin/filters.py +++ b/django/contrib/admin/filters.py @@ -251,10 +251,7 @@ class BooleanFieldListFilter(FieldListFilter): } -FieldListFilter.register( - lambda f: isinstance(f, (models.BooleanField, models.NullBooleanField)), - BooleanFieldListFilter -) +FieldListFilter.register(lambda f: isinstance(f, models.BooleanField), BooleanFieldListFilter) class ChoicesFieldListFilter(FieldListFilter): diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 73bcd8bcbb4..add7faba561 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -396,7 +396,7 @@ def display_for_field(value, field, empty_value_display): return dict(field.flatchoices).get(value, empty_value_display) # BooleanField needs special-case null-handling, so it comes before the # general null test. - elif isinstance(field, (models.BooleanField, models.NullBooleanField)): + elif isinstance(field, models.BooleanField): return _boolean_icon(value) elif value is None: return empty_value_display diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 59cc963b18b..44052a7bc36 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -1956,10 +1956,10 @@ class GenericIPAddressField(Field): }) -class NullBooleanField(Field): - empty_strings_allowed = False +class NullBooleanField(BooleanField): default_error_messages = { 'invalid': _("'%(value)s' value must be either None, True or False."), + 'invalid_nullable': _("'%(value)s' value must be either None, True or False."), } description = _("Boolean (Either True, False or None)") @@ -1977,35 +1977,6 @@ class NullBooleanField(Field): def get_internal_type(self): return "NullBooleanField" - def to_python(self, value): - if value is None: - return None - if value in (True, False): - return bool(value) - if value in ('None',): - return None - 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 get_prep_value(self, value): - value = super().get_prep_value(value) - if value is None: - return None - return self.to_python(value) - - def formfield(self, **kwargs): - return super().formfield(**{ - 'form_class': forms.NullBooleanField, - **kwargs, - }) - class PositiveIntegerRelDbTypeMixin: