v0.166.0
 1from typing import Any
 2
 3from plain import exceptions
 4
 5from .base import DefaultableField
 6
 7
 8class BooleanField[T: (bool, bool | None) = bool](DefaultableField[T]):
 9    db_type_sql = "boolean"
10    empty_strings_allowed = False
11
12    def to_python(self, value: Any) -> bool | None:
13        if self.allow_null and value in self.empty_values:
14            return None
15        if value in (True, False):
16            # 1/0 are equal to True/False. bool() converts former to latter.
17            return bool(value)
18        if value in ("t", "True", "1"):
19            return True
20        if value in ("f", "False", "0"):
21            return False
22        if self.allow_null:
23            message = '"%(value)s" value must be either True, False, or None.'
24        else:
25            message = '"%(value)s" value must be either True or False.'
26        raise exceptions.ValidationError(
27            message,
28            code="invalid",
29            params={"value": value},
30        )
31
32    def get_prep_value(self, value: Any) -> Any:
33        value = super().get_prep_value(value)
34        if value is None:
35            return None
36        return self.to_python(value)