{"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":"python","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,"search_vec":"'8.4.0':51 'accord':43 'activ':57 'cadenc':59 'convers':39 'current':48 'django':1,6,11,30,67 'django-phonenumber-field':5 'field':4,8,28 'form':33,71 'format':37 'googl':15 'handl':35 'i18n':73 'integr':14 'intern':25,45 'libphonenumb':17,74 'librari':12,54 'maintain':55 'minor/patch':62 'model':31,72 'multipl':61 'number':3,27,42,69 'phone':2,26,41,68 'phonenumb':7,21 'provid':23 'python':20 'python-phonenumb':19 'releas':58,63 'standard':46 'throughout':64 'valid':36,70 'version':49 'via':18 'year':66","created_at":"2026-04-09T18:39:19.490730+00:00","updated_at":"2026-04-16T14:33:35.721107+00:00","problems":[{"fix":"Ensure the package is installed using `pip install django-phonenumber-field[phonenumbers]` (or `django-phonenumber-field[phonenumberslite]` for a lighter version), and `phonenumber_field` is added to `INSTALLED_APPS` in your Django `settings.py`.","cause":"This error typically means the `django-phonenumber-field` package, or its underlying `phonenumbers` dependency, was not correctly installed or is not accessible in the Python environment where Django is running. The package itself is installed as `django-phonenumber-field` but imported as `phonenumber_field`.","error":"ModuleNotFoundError: No module named 'phonenumber_field'"},{"fix":"Set `PHONENUMBER_DEFAULT_REGION = 'US'` (or your desired ISO 3166-1 two-letter country code) in your `settings.py` file to provide a default region for national number parsing, or ensure users always enter numbers with an international prefix (e.g., `+12125552368`).","cause":"This validation error occurs when a user enters a national phone number without an international prefix, and the `PHONENUMBER_DEFAULT_REGION` setting is not defined in Django's `settings.py`, or it's set to a region different from the entered number.","error":"Enter a valid phone number (e.g. +12125552368) or a number with an international call prefix."},{"fix":"The `PhoneNumberField` on a model returns a `PhoneNumber` object. Access the formatting properties on this object. For example, if `phone_number` is your field, use `my_instance.phone_number.as_international`.","cause":"This error happens when you try to access formatting properties like `as_international`, `as_national`, `as_e164`, or `as_rfc3966` directly on the model field instance (`my_model.phone_number`) rather than on the `PhoneNumber` object that the field stores or returns.","error":"AttributeError: 'PhoneNumberField' object has no attribute 'as_international'"},{"fix":"Import `PhoneNumberField` from the correct location: `from phonenumber_field.formfields import PhoneNumberField` when defining forms, or `from phonenumber_field.modelfields import PhoneNumberField` when defining model fields.","cause":"This error indicates that you are attempting to import `PhoneNumberField` from `django.forms`, but the field provided by `django-phonenumber-field` is not part of Django's core forms module.","error":"module 'django.forms' has no attribute 'PhoneNumberField'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"8.5.0","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/stefanfoulis/django-phonenumber-field","docs":"https://django-phonenumber-field.readthedocs.io/","changelog":"https://github.com/stefanfoulis/django-phonenumber-field/releases/","pypi":"https://pypi.org/project/django-phonenumber-field/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["web-framework","serialization","database","auth-security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}