Built-in Form Field Types
Built-in form fields in this codebase provide the logic for validating input data and converting it into Python objects. These fields are defined in django/forms/fields.py and handle everything from simple text normalization to complex multi-part data processing.
Text Fields
Text-based fields inherit from CharField and focus on string manipulation and pattern validation.
CharField
The base for most text input, CharField (found in django/forms/fields.py) handles basic string cleaning. By default, it strips leading and trailing whitespace via the strip=True argument in __init__. It also appends a ProhibitNullCharactersValidator to prevent null bytes in the input.
# django/forms/fields.py
class CharField(Field):
def __init__(self, *, max_length=None, min_length=None, strip=True, empty_value="", **kwargs):
self.max_length = max_length
self.min_length = min_length
self.strip = strip
self.empty_value = empty_value
super().__init__(**kwargs)
# ... adds MinLengthValidator and MaxLengthValidator if provided
Specialized Text Fields
- EmailField: A
CharFieldthat usesvalidators.validate_email. It defaultsmax_lengthto 320 characters to comply with RFC 3696. - URLField: Automatically prepends a scheme (defaulting to
https) if the input lacks one. This is managed by theassume_schemeparameter in__init__and logic into_python. - RegexField: Validates input against a regular expression. It can take a string or a compiled regex object, which it wraps in a
validators.RegexValidator. - SlugField: Specifically for slugs (letters, numbers, underscores, or hyphens). It supports Unicode slugs if
allow_unicode=Trueis passed. - UUIDField: Validates that the input is a valid UUID string and returns a
uuid.UUIDobject.
Numeric Fields
Numeric fields handle type conversion and range validation, often interacting with HTML5 number inputs.
IntegerField and FloatField
IntegerField uses int() for conversion and supports min_value, max_value, and step_size. FloatField inherits from IntegerField but uses float() for conversion and includes a check for finite numbers in its validate method using math.isfinite().
DecimalField
For fixed-precision math, DecimalField returns Python Decimal objects. It requires max_digits and decimal_places for validation via validators.DecimalValidator.
# django/forms/fields.py
class DecimalField(IntegerField):
def to_python(self, value):
if value in self.empty_values:
return None
if self.localize:
value = formats.sanitize_separators(value)
try:
value = Decimal(str(value))
except DecimalException:
raise ValidationError(self.error_messages["invalid"], code="invalid")
return value
Date and Time Fields
Temporal fields convert string inputs into Python datetime objects. They all inherit from BaseTemporalField and use input_formats to attempt parsing against multiple patterns.
- DateField: Returns
datetime.date. - TimeField: Returns
datetime.time. - DateTimeField: Returns
datetime.datetime. It handles timezone awareness inprepare_valueandto_pythonusingto_current_timezoneandfrom_current_timezone. - DurationField: Converts strings (like "1 00:00:00") into
datetime.timedeltaobjects usingparse_duration. - SplitDateTimeField: A
MultiValueFieldthat uses two separate widgets (date and time) to produce a singledatetime.datetimeobject.
Choice Fields
Choice fields restrict input to a predefined set of options.
ChoiceField and MultipleChoiceField
ChoiceField validates that the submitted value exists within its choices attribute. Setting choices on the field automatically updates the associated widget's choices. MultipleChoiceField allows selecting multiple options and returns them as a list of strings.
Typed Variants
TypedChoiceField and TypedMultipleChoiceField allow for automatic type conversion of the selected value(s) via a coerce function.
# Example usage from tests/forms_tests/field_tests/test_typedchoicefield.py
f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int)
# f.clean("1") returns 1 (as an integer)
FilePathField
A specialized choice field where the choices are dynamically generated from the filesystem. It supports path, match (regex), and recursive parameters to filter files or folders.
Boolean Fields
Boolean fields handle the nuances of web-submitted "truthy" and "falsy" values.
- BooleanField: Uses a
CheckboxInputwidget. A critical implementation detail is that ifrequired=True(the default), the field will only validate if the checkbox is actually checked. - NullBooleanField: Designed for three-state logic (True, False, None). Its
to_pythonmethod explicitly handles strings like "True", "False", "1", "0", "true", and "false" to accommodate various JavaScript serializations and radio button submissions.
Advanced and Composite Fields
These fields handle complex data structures or combine multiple fields into one.
JSONField
JSONField allows users to input JSON-encoded data. It uses json.loads in to_python and json.dumps in prepare_value. If the input is invalid JSON, it returns an InvalidJSONInput object, which allows the form to re-display the invalid string to the user for correction.
GenericIPAddressField
Validates IPv4 or IPv6 addresses. It can be configured via the protocol argument ("both", "ipv4", or "ipv6") and can "unpack" IPv4-mapped IPv6 addresses (e.g., ::ffff:192.0.2.1 to 192.0.2.1) if unpack_ipv4=True.
MultiValueField and ComboField
These fields aggregate other fields:
- MultiValueField: An abstract class for fields that take multiple inputs (like
SplitDateTimeField). Subclasses must implementcompress()to combine the list of cleaned values into a single value. - ComboField: Validates a single input against a sequence of different fields. For example, a
ComboFieldcould ensure a string is both a validCharFieldwith a specific length and a validEmailField.
# django/forms/fields.py
class ComboField(Field):
def clean(self, value):
super().clean(value)
for field in self.fields:
value = field.clean(value)
return value