django-phonenumber-field

A Django model and form field for validating, storing, and formatting international phone numbers via libphonenumber.

Library
PyPI
v8.5.0
1,550stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
71/100Good
Development Activity68
Maintenance48
Community80
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture78
Code Quality82
Innovation55
Learning Curve85

django-phonenumber-field is a Django library that wraps Google’s libphonenumber engine (via the python-phonenumbers port) into a first-class Django model field, form field, and DRF serializer field. It parses, validates, normalizes, and formats international phone numbers so applications don’t need to hand-roll regex-based validation or manage country-specific formatting rules themselves.

The library exposes a PhoneNumberField for Django models that stores numbers in a configurable canonical format (E164 by default), a matching form field with region-aware widgets including a country-prefix picker, and a PhoneNumber class that extends phonenumbers.PhoneNumber with convenient properties like as_international, as_e164, and as_national. Maintained since 2011, it’s a common dependency in Django projects that collect phone numbers, from user profiles to two-factor authentication flows.

What You Get

  • Django model field (PhoneNumberField) that validates and stores phone numbers in a configurable canonical format
  • Matching Django form field with automatic validation and region-aware widgets
  • PhoneNumberPrefixWidget for split country-code + national-number input
  • RegionalPhoneNumberWidget that displays numbers in national format when they match the configured region
  • Django REST Framework serializer field for API validation
  • PhoneNumber value object with formatting helpers (as_international, as_e164, as_national, as_rfc3966)
  • Optional Babel integration for localized formatting

Common Use Cases

  • Validating and storing user phone numbers on Django user/profile models
  • Collecting phone numbers in Django forms with country-aware input widgets
  • Exposing phone number fields through Django REST Framework APIs
  • Normalizing inconsistently formatted phone numbers from CSV imports or third-party data before storage
  • Enforcing region-specific phone number formats for a single-country application via PHONENUMBER_DEFAULT_REGION

Under The Hood

Architecture The library is organized around a small set of focused modules: phonenumber.py defines a PhoneNumber value object subclassing phonenumbers.PhoneNumber with pythonic formatting properties and custom equality/ordering that compares canonical string representations; modelfields.py defines PhoneNumberField(models.CharField) plus a PhoneNumberDescriptor that coerces assigned values through to_python() on __set__; formfields.py and widgets.py layer Django forms integration (including a MultiWidget-based country-prefix picker) on top of the same conversion logic; serializerfields.py adapts the same validation for Django REST Framework. All entry points funnel through the shared to_python()/PhoneNumber.from_string() functions in phonenumber.py, so parsing and normalization behavior stays consistent across models, forms, and serializers — a change to that core module propagates everywhere numbers are handled.

Tech Stack Pure Python (3.10+) with Django 5.2+ as a required dependency and phonenumbers (or the lighter phonenumberslite) as an optional extra providing the actual libphonenumber parsing/validation/formatting engine. Packaging uses setuptools with setuptools_scm for git-tag-derived versioning, and an optional Babel extra enables locale-aware number formatting. No database driver or web framework beyond Django itself; the library is a thin, dependency-light integration layer.

Code Quality The project has a substantial test suite (tests/test_phonenumber.py, test_formfields.py, test_widgets.py, test_serializers.py, plus a general tests.py) covering model field behavior, form validation, widget rendering, and DRF serialization, run across the Python/Django support matrix via tox with combined coverage reporting and CI (GitHub Actions Test workflow, badge in the README). Code style is enforced with ruff (pyflakes, pycodestyle, isort, bugbear, comprehensions, pyupgrade rules configured in pyproject.toml). Naming and error handling are explicit and idiomatic Django (custom checks.Error integration for configuration validation, typed exceptions like TypeError/ValueError for invalid conversions).

What Makes It Unique Rather than validating phone numbers with regex heuristics, it delegates entirely to Google’s libphonenumber (the same engine behind Android’s phone number handling) for parsing and validation, then wraps that engine’s output in Django-native abstractions — a model field with a real value-object descriptor, a DRF serializer field, and multiple widget strategies (split country-code input, region-aware national-format display) that most hand-rolled phone validation implementations don’t attempt to replicate.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search