Network and Identity Validation
This project provides specialized validators for verifying complex network-related strings such as email addresses, domain names, and URLs. These validators are located in django/core/validators.py and are designed to be RFC-compliant while remaining flexible for custom requirements.
Email Validation
The EmailValidator class handles the verification of email addresses. It ensures that an address follows the standard user@domain format and adheres to length constraints defined in RFC 3696.
Core Logic
The validation process in EmailValidator.__call__ follows these steps:
- Length Check: Ensures the total length does not exceed 320 characters.
- Split: Divides the string into a
user_partand adomain_partat the last@symbol. - User Validation: Matches the
user_partagainstuser_regex, which supports both "dot-atom" and "quoted-string" formats. - Domain Validation: Checks the
domain_partagainst an allowlist or validates it usingvalidate_domain_part.
Customizing Domains
By default, the validator allows localhost via the domain_allowlist. You can extend this to support internal or non-standard domains that might not pass the standard domain regex.
from django.core.validators import EmailValidator
# Allow internal server domains
validator = EmailValidator(allowlist=["internal.server", "local.dev"])
validator("admin@internal.server") # Valid
The validate_domain_part method also supports literal IP addresses (IPv4 and IPv6) enclosed in brackets, such as user@[192.168.1.1].
URL Validation
The URLValidator class is a RegexValidator subclass that provides comprehensive verification for URLs, including scheme, authentication, host, port, and path.
Validation Workflow
Unlike simple regex validators, URLValidator performs several distinct checks:
- Scheme Verification: It extracts the scheme (the part before
://) and ensures it exists in theschemeslist (default:http,https,ftp,ftps). - Regex Match: It uses a complex regex to verify the overall structure, including optional user/password authentication and ports.
- Host Constraints: It uses
urlsplitto extract the hostname and ensures it does not exceed 253 characters (per RFC 1034). - IPv6 Handling: If the host appears to be an IPv6 address (enclosed in brackets), it calls
validate_ipv6_addressfor specialized verification.
Custom Schemes
You can instantiate URLValidator with a custom list of allowed protocols:
from django.core.validators import URLValidator
# Validate git and ssh protocols
validate_git = URLValidator(schemes=["git", "ssh"])
validate_git("git://github.com/django/django.git")
Domain Name Validation
The DomainNameValidator is used to verify that a string is a valid domain name. It is the foundation for domain checks in both EmailValidator and URLValidator.
Internationalized Domain Names (IDNA)
By default, DomainNameValidator supports Unicode characters in domain names (IDNA). This is controlled by the accept_idna parameter. When True, it uses regex patterns that include the Unicode range \u00a1-\uffff.
If you require strict ASCII-only domain validation, you can disable this:
from django.core.validators import DomainNameValidator
# Reject Unicode domains
strict_validator = DomainNameValidator(accept_idna=False)
# strict_validator("ıçğü.com") would raise ValidationError
Constraints
- Label Length: Individual domain labels (parts between dots) are limited to 63 characters.
- Total Length: The entire domain name is limited to 255 characters.
- Structure: It ensures domains do not start or end with dashes and includes TLD (Top-Level Domain) verification.
Integration with Model Fields
These validators are automatically integrated into Django's model layer through specialized fields in django/db/models/fields/__init__.py.
- EmailField: Uses the pre-instantiated
validate_email(an instance ofEmailValidator). It defaults to amax_lengthof 254 to be compliant with RFCs 3696 and 5321. - URLField: Uses
URLValidator()as a default validator and defaults to amax_lengthof 200.
from django.db import models
class Profile(models.Model):
website = models.URLField() # Uses URLValidator
contact_email = models.EmailField() # Uses EmailValidator
When these fields are used, validation occurs both at the database model level and when generating corresponding form fields.