Skip to main content

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 CharField that uses validators.validate_email. It defaults max_length to 320 characters to comply with RFC 3696.
  • URLField: Automatically prepends a scheme (defaulting to https) if the input lacks one. This is managed by the assume_scheme parameter in __init__ and logic in to_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=True is passed.
  • UUIDField: Validates that the input is a valid UUID string and returns a uuid.UUID object.

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 in prepare_value and to_python using to_current_timezone and from_current_timezone.
  • DurationField: Converts strings (like "1 00:00:00") into datetime.timedelta objects using parse_duration.
  • SplitDateTimeField: A MultiValueField that uses two separate widgets (date and time) to produce a single datetime.datetime object.

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 CheckboxInput widget. A critical implementation detail is that if required=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_python method 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 implement compress() 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 ComboField could ensure a string is both a valid CharField with a specific length and a valid EmailField.
# 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