The PhoneNumber wrapper

class phonenumber_field.phonenumber.PhoneNumber

A extended version of phonenumbers.PhoneNumber that provides some neat and more pythonic, easy to access methods. This makes using a PhoneNumber instance much easier, especially in templates and such.

classmethod from_string(phone_number, region=None) Self
Parameters:
  • phone_number (str) – parse this str as a phone number.

  • region (str) – 2-letter country code as defined in ISO 3166-1. When not supplied, defaults to PHONENUMBER_DEFAULT_REGION

is_valid()

Whether the number supplied is actually valid.

Returns:

True when the phone number is valid.

Return type:

bool

property as_international
property as_national
property as_e164
property as_rfc3966

Usage

>>> from phonenumber_field.phonenumber import PhoneNumber

>>> number = PhoneNumber.from_string("+16044011234")
>>> print(number.as_national)
(604) 401-1234
>>> print(number.as_e164)
+16044011234
>>> print(number.as_international)
+1 604-401-1234
>>> print(number.as_rfc3966)
tel:+1-604-401-1234

# Using national numbers with the region keyword argument.
>>> canadian_number = "(604) 401 1234"
>>> number = PhoneNumber.from_string(canadian_number, region="CA")
>>> print(number.as_e164)
+16044011234

Model field

The PhoneNumberField model field allows storing PhoneNumbers in the database, based on a CharField.

The phone number format used by the database is controlled with PHONENUMBER_DB_FORMAT. When no region is specified, a phone number in the "NATIONAL" format will be assumed to be from the PHONENUMBER_DEFAULT_REGION.

class phonenumber_field.modelfields.PhoneNumberField(*args, region=None, **kwargs)
__init__(*args, region=None, **kwargs)
Parameters:
  • region (str) – 2-letter country code as defined in ISO 3166-1. When not supplied, defaults to PHONENUMBER_DEFAULT_REGION

  • max_length (int) – The maximum length of the underlying char field.

Usage

from django.db import models
from phonenumber_field.modelfields import PhoneNumberField


class Customer(models.Model):
    name = models.TextField()
    # An optional phone number.
    phone_number = PhoneNumberField(blank=True)

Form field

The PhoneNumberField form field to validate PhoneNumber, based on a CharField.

class phonenumber_field.formfields.PhoneNumberField(*args, region=None, widget=None, **kwargs)
__init__(*args, region=None, widget=None, **kwargs)
Parameters:

Usage

>>> from django import forms
>>> from phonenumber_field.formfields import PhoneNumberField

>>> class PhoneForm(forms.Form):
...     number = PhoneNumberField(region="CA")
...

# Manipulating data
>>> form = PhoneForm({"number": "+1 604 401 1234"})
>>> form.is_valid()
True
>>> form.cleaned_data
{'number': PhoneNumber(country_code=1, national_number=6044011234, extension=None, italian_leading_zero=None, number_of_leading_zeros=None, country_code_source=1, preferred_domestic_carrier_code=None)}
>>> print_html(form.as_div())
<div>
 <label for="id_number">
  Number:
 </label>
 <input id="id_number" name="number" required="" type="tel" value="(604) 401-1234"/>
</div>

# Handling errors
>>> form = PhoneForm({"number": "invalid"})
>>> form.is_valid()
False
>>> print_html(form.as_div())
<div>
 <label for="id_number">
  Number:
 </label>
 <ul class="errorlist">
  <li>
   Enter a valid phone number (e.g. (506) 234-5678) or a number with an international call prefix.
  </li>
 </ul>
 <input aria-invalid="true" id="id_number" name="number" required="" type="tel" value="invalid"/>
</div>

Note

Because the PhoneNumberField specifies a region, the example number is a national number from that region. When no region is specified, an international example phone number in the E.164 format is suggested.

Widgets

RegionalPhoneNumberWidget

Default widget for PhoneNumberField.

  • input_type: tel

  • Renders as <input type="tel" >

Important

The region should be specified (either per field using the region keyword argument, or with the PHONENUMBER_DEFAULT_REGION setting) in order to know which national number format to recognize.

class phonenumber_field.widgets.RegionalPhoneNumberWidget(region=None, attrs=None)

A Widget that prefers displaying numbers in the national format, and falls back to PHONENUMBER_DEFAULT_FORMAT for international numbers.

__init__(region=None, attrs=None)
Parameters:

Usage

>>> from django import forms
>>> from phonenumber_field.formfields import PhoneNumberField

>>> class CanadianPhoneForm(forms.Form):
...     # RegionalPhoneNumberWidget is the default widget.
...     number = PhoneNumberField(region="CA")
...

# Using the national format for the field’s region.
>>> form = CanadianPhoneForm({"number": "+16044011234"})
>>> print_html(form.as_div())
<div>
 <label for="id_number">
  Number:
 </label>
 <input id="id_number" name="number" required="" type="tel" value="(604) 401-1234"/>
</div>

# Using E164 for an international number.
>>> french_number = "+33612345678"
>>> form = CanadianPhoneForm({"number": french_number})
>>> print_html(form.as_div())
<div>
 <label for="id_number">
  Number:
 </label>
 <input id="id_number" name="number" required="" type="tel" value="+33612345678"/>
</div>

PhoneNumberPrefixWidget

Important

Requires the Babel package be installed.

class phonenumber_field.widgets.PhoneNumberPrefixWidget(attrs=None, initial=None, country_attrs=None, country_choices=None, number_attrs=None, region=None)

A Widget that splits a phone number into fields:

  • a Select for the country (phone prefix)

  • a TextInput for local phone number

__init__(attrs=None, initial=None, country_attrs=None, country_choices=None, number_attrs=None, region=None)
Parameters:
  • attrs (dict) – See attrs

  • initial (dict) – See initial

  • country_attrs (dict) – The attrs for the country Select.

  • country_choices (list of 2-tuple, optional The first element is the value, which must match a country code recognized by the phonenumbers project. The second element is the label.) – Limit the country choices.

  • number_attrs (dict) – The attrs for the local phone number TextInput.

  • region (str) – 2-letter country code as defined in ISO 3166-1. When not supplied, defaults to PHONENUMBER_DEFAULT_REGION

Usage

>>> from django import forms
>>> from phonenumber_field.formfields import PhoneNumberField
>>> from phonenumber_field.widgets import PhoneNumberPrefixWidget

# Limiting country choices.
>>> class CanadianPhoneForm(forms.Form):
...     # RegionalPhoneNumberWidget is the default widget.
...     number = PhoneNumberField(
...         region="CA",
...         widget=PhoneNumberPrefixWidget(
...             country_choices=[
...                  ("CA", "Canada"),
...                  ("FR", "France"),
...             ],
...         ),
...     )
...

>>> form = CanadianPhoneForm({"number_0": "CA", "number_1": "6044011234"})
>>> print_html(form.as_div())
<div>
 <fieldset>
  <legend>
   Number:
  </legend>
  <select id="id_number_0" name="number_0" required="">
   <option selected="" value="CA">
    Canada
   </option>
   <option value="FR">
    France
   </option>
  </select>
  <input id="id_number_1" name="number_1" required="" type="text" value="6044011234"/>
 </fieldset>
</div>

# Pre-selecting a country.
>>> class FrenchPhoneForm(forms.Form):
...     # RegionalPhoneNumberWidget is the default widget.
...     number = PhoneNumberField(
...         region="FR",
...         widget=PhoneNumberPrefixWidget(
...             initial="FR",
...             country_choices=[
...                  ("CA", "Canada"),
...                  ("FR", "France"),
...             ],
...         ),
...     )
...

>>> form = FrenchPhoneForm()
>>> print_html(form.as_div())
<div>
 <fieldset>
  <legend>
   Number:
  </legend>
  <select id="id_number_0" name="number_0" required="">
   <option value="CA">
    Canada
   </option>
   <option selected="" value="FR">
    France
   </option>
  </select>
  <input id="id_number_1" name="number_1" required="" type="text"/>
 </fieldset>
</div>

Serializer field

The PhoneNumberField serializer field, based on the CharField.

The serialization format is controlled by the PHONENUMBER_DEFAULT_FORMAT.

class phonenumber_field.serializerfields.PhoneNumberField(*args, **kwargs)
__init__(*args, region=None, **kwargs)
Parameters:

region (str) – 2-letter country code as defined in ISO 3166-1. When not supplied, defaults to PHONENUMBER_DEFAULT_REGION

Usage

>>> from django.conf import settings
>>> from rest_framework import renderers, serializers
>>> from phonenumber_field.serializerfields import PhoneNumberField

>>> class PhoneNumberSerializer(serializers.Serializer):
...     number = PhoneNumberField(region="CA")
...

>>> serializer = PhoneNumberSerializer(data={"number": "604 401 1234"})
>>> serializer.is_valid()
True
>>> serializer.validated_data
OrderedDict([('number', PhoneNumber(country_code=1, national_number=6044011234, extension=None, italian_leading_zero=None, number_of_leading_zeros=None, country_code_source=20, preferred_domestic_carrier_code=None))])

# Using the PHONENUMBER_DEFAULT_FORMAT.
>>> renderers.JSONRenderer().render(serializer.data)
b'{"number":"+16044011234"}'

Validator

Validates:

Note

Not all well-formed phone numbers are valid. The rules to construct phone numbers vary per region of the world.

Falsehoods Programmers Believe About Phone Numbers is a good read.

phonenumber_field.validators.validate_international_phonenumber(value)

code: "invalid_phone_number"

Settings

Phone number format choices

Setting value

International

Extensions

Notes

"E164" (default)

https://en.wikipedia.org/wiki/E.164

"INTERNATIONAL"

https://en.wikipedia.org/wiki/E.123#Telephone_number

"RFC3966"

https://www.rfc-editor.org/rfc/rfc3966.html

"NATIONAL"

DISCOURAGED, requires PHONENUMBER_DEFAULT_REGION

Warning

By default, the library uses E.164, the international public telecommunication numbering plan, which does not support phone numbers extensions. Set both PHONENUMBER_DB_FORMAT and PHONENUMBER_DEFAULT_FORMAT to an extension-compatible format to handle phone numbers extensions.

PHONENUMBER_DB_FORMAT

Store phone numbers strings in the specified format in the database.

Default: "E164".

See Phone number format choices.

Warning

Data loss may occur when changing the DB format.

Phone numbers stored in the database are parsed every time they are loaded from the database.

When switching from a format that can represent extensions to a format that cannot, the extension information is definitely lost.

When using PHONENUMBER_DB_FORMAT="NATIONAL", changing the PHONENUMBER_DEFAULT_REGION will cause phone numbers stored in the database to be interpreted differently, resulting in data corruption.

PHONENUMBER_DEFAULT_FORMAT

String formatting of phone numbers.

Default: "E164".

See Phone number format choices.

PHONENUMBER_DEFAULT_REGION

ISO-3166-1 two-letter country code indicating how to interpret regional phone numbers.

Default: None.