{"id":2002,"library":"django-phonenumber-field","title":"Django Phone Number Field","description":"django-phonenumber-field is a Django library that integrates Google's `libphonenumber` (via `python-phonenumbers`) to provide an international phone number field for Django models and forms. It handles validation, formatting, and conversion of phone numbers according to international standards. The current version is 8.4.0, and the library maintains an active release cadence with multiple minor/patch releases throughout the year.","status":"active","version":"8.4.0","language":"en","source_language":"en","source_url":"https://github.com/stefanfoulis/django-phonenumber-field","tags":["django","phone number","validation","forms","models","i18n","libphonenumber"],"install":[{"cmd":"pip install django-phonenumber-field[phonenumbers]","lang":"bash","label":"Recommended (includes phonenumbers)"},{"cmd":"pip install django-phonenumber-field[phonenumberslite]","lang":"bash","label":"Alternative (lower memory footprint)"}],"dependencies":[{"reason":"Core library for phone number parsing, validation, and formatting (installed via extra `[phonenumbers]`).","package":"phonenumbers","optional":false},{"reason":"Alternative to `phonenumbers` with a lower memory footprint (installed via extra `[phonenumberslite]`).","package":"phonenumberslite","optional":true},{"reason":"Required for `RegionalPhoneNumberWidget` to display example phone numbers based on region.","package":"Babel","optional":true}],"imports":[{"symbol":"PhoneNumberField","correct":"from phonenumber_field.modelfields import PhoneNumberField"},{"symbol":"PhoneNumberField (form field)","correct":"from phonenumber_field.formfields import PhoneNumberField"},{"symbol":"SplitPhoneNumberField (form field for prefix/number split input)","correct":"from phonenumber_field.formfields import SplitPhoneNumberField"},{"note":"A Pythonic wrapper around phonenumbers.PhoneNumber objects.","symbol":"PhoneNumber","correct":"from phonenumber_field.phonenumber import PhoneNumber"},{"note":"PhoneNumberInternationalFallbackWidget was removed in v8.0.0. Use RegionalPhoneNumberWidget instead.","wrong":"from phonenumber_field.widgets import PhoneNumberInternationalFallbackWidget","symbol":"RegionalPhoneNumberWidget","correct":"from phonenumber_field.widgets import RegionalPhoneNumberWidget"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\nfrom django.db import models\nfrom phonenumber_field.modelfields import PhoneNumberField\n\nsettings.configure(\n    INSTALLED_APPS=['phonenumber_field'],\n    DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},\n    PHONENUMBER_DEFAULT_REGION='US' # Crucial for national formats\n)\ndjango.setup()\n\nclass Contact(models.Model):\n    name = models.CharField(max_length=100)\n    phone_number = PhoneNumberField(blank=True)\n\n    def __str__(self):\n        return f\"{self.name}: {self.phone_number}\"\n\n# Example Usage:\n# from django.core.management import call_command\n# call_command('makemigrations', 'myapp') # if using in a real app\n# call_command('migrate') # if using in a real app\n\ncontact1 = Contact.objects.create(name=\"Alice\", phone_number=\"+12025550123\")\ncontact2 = Contact.objects.create(name=\"Bob\", phone_number=\"6502530000\") # Assumes PHONENUMBER_DEFAULT_REGION='US'\n\nprint(contact1)\nprint(contact2)\nprint(contact1.phone_number.as_e164)\nprint(contact2.phone_number.as_national)\n\n# Example with an invalid number (will raise ValidationError in a real form/model save)\n# try:\n#     Contact.objects.create(name=\"Invalid\", phone_number=\"123\")\n# except Exception as e:\n#     print(f\"Caught expected error: {e}\")","lang":"python","description":"To quickly use `django-phonenumber-field`, first add `phonenumber_field` to your `INSTALLED_APPS` in `settings.py`. Then define a `PhoneNumberField` in your Django model. For national number formats and proper validation, it's recommended to set `PHONENUMBER_DEFAULT_REGION` in your settings. The field automatically handles `PhoneNumber` objects, providing methods for various formats like E.164, national, and international."},"warnings":[{"fix":"Replace `PhoneNumberInternationalFallbackWidget` with `RegionalPhoneNumberWidget` in your forms or widget definitions.","message":"The `PhoneNumberInternationalFallbackWidget` was removed in version 8.0.0. If you were using it, you should switch to `phonenumber_field.widgets.RegionalPhoneNumberWidget` instead.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"Refactor custom validation logic to align with Django's form field validation, moving checks to the form's `clean_FIELD()` or `clean()` methods. Update any `invalid_phone_number` error codes to `invalid`.","message":"In version 8.0.0, validation logic was moved from widgets to form fields. This changes how custom validation on `PhoneNumberField`s works. If you had `clean_FIELD()` or `clean()` methods that relied on the widget's previous validation behavior, you may need to review and adjust them. Error codes like `invalid_phone_number` might need to be changed to `invalid`.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"Test your application thoroughly after upgrading to 7.2.0 or later, especially if you rely on `values_list()` or raw database interactions with `PhoneNumberField` values.","message":"Version 7.2.0 introduced a database converter for the model field. This change, though intended as a fix for `values_list()` behavior, was retrospectively considered a breaking change as it could affect existing code.","severity":"breaking","affected_versions":">=7.2.0"},{"fix":"Always set `PHONENUMBER_DEFAULT_REGION` (e.g., `PHONENUMBER_DEFAULT_REGION = 'US'`) in your Django `settings.py`.","message":"The `PHONENUMBER_DEFAULT_REGION` setting is critical for the library to correctly interpret and validate national phone numbers. Without it, numbers in 'NATIONAL' format may not be recognized or validated properly.","severity":"gotcha","affected_versions":"All"},{"fix":"You may need to apply custom CSS or use Django's template rendering features to manually position the `PhoneNumberPrefixWidget` and the national number input side-by-side.","message":"When using `SplitPhoneNumberField` (which renders a separate input for the prefix and the national number), applying default CSS frameworks like Bootstrap might cause the prefix and number fields to display on separate lines instead of inline.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure that any string values assigned to `PhoneNumberField` instances include the country code (e.g., `'+12025550123'`) or explicitly parse it with a region if it's a national number, e.g., `PhoneNumber.from_string('6044011234', region='CA')`.","message":"While `PhoneNumberField` is based on `CharField` internally, it stores and retrieves `PhoneNumber` objects, not plain strings. When directly assigning a string value to a `PhoneNumberField` in Python code (e.g., `model_instance.phone_number = '+1234567890'`), the string must include the country code for correct parsing and validation.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}