I am storing a phone number in model
like this:
phone_number = models.CharField(max_length=12)
The user would enter a phone number and I would use the phone number for SMS authentication. This application would be used globally. So I would also need a country code. Is CharField
a good way to store a phone number? And, how do I validate the phone number?
You might actually look into the internationally standardized format E.164, recommended by Twilio for example (who have a service and an API for sending SMS or phone-calls via REST requests).
This is likely to be the most universal way to store phone numbers, in particular if you have international numbers work with.
Phone by PhoneNumberField
You can use the phonenumber_field
library. It is a port of Google's libphonenumber library, which powers Android's phone number handling. See django-phonenumber-field.
In the model:
from phonenumber_field.modelfields import PhoneNumberField
class Client(models.Model, Importable):
phone = PhoneNumberField(null=False, blank=False, unique=True)
In the form:
from phonenumber_field.formfields import PhoneNumberField
class ClientForm(forms.Form):
phone = PhoneNumberField()
Get the phone as a string from an object field:
client.phone.as_e164
Normalize the phone string (for tests and other staff):
from phonenumber_field.phonenumber import PhoneNumber
phone = PhoneNumber.from_string(phone_number=raw_phone, region='RU').as_e164
Phone by regexp
One note for your model: E.164 numbers have a maximum character length of 15.
To validate, you can employ some combination of formatting and then attempting to contact the number immediately to verify.
I believe I used something like the following in my django project:
class ReceiverForm(forms.ModelForm):
phone_number = forms.RegexField(regex=r'^\+?1?\d{9,15}$',
error_message = ("Phone number must be entered in the format: '+999999999'. Up to 15 digits is allowed."))
As per jpotter6, you can do something like the following in your models as well:
File models.py:
from django.core.validators import RegexValidator
class PhoneModel(models.Model):
...
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True) # Validators should be a list