Permit mixed casing of string values for BooleanField validation by neckenth · Pull Request #8970 · encode/django-rest-framework (original) (raw)

This is a good fix.

I initially thought that Django itself simply works with bool to cast a str but that's not the case. Here's Django's BooleanField.

class BooleanField(Field): widget = CheckboxInput

def to_python(self, value):
    """Return a Python boolean object."""
    # Explicitly check for the string 'False', which is what a hidden field
    # will submit for False. Also check for '0', since this is what
    # RadioSelect will provide. Because bool("True") == bool('1') == True,
    # we don't need to handle that explicitly.
    if isinstance(value, str) and value.lower() in ("false", "0"):
        value = False
    else:
        value = bool(value)
    return super().to_python(value)

def validate(self, value):
    if not value and self.required:
        raise ValidationError(self.error_messages["required"], code="required")

def has_changed(self, initial, data):
    if self.disabled:
        return False
    # Sometimes data or initial may be a string equivalent of a boolean
    # so we should run it through to_python first to get a boolean value
    return self.to_python(initial) != self.to_python(data)

Django performs explicit checks too. The comments suggest that they're there to handle output of the form fields.