Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate phone number in django?

I'm currently using phonenumbers package as a validation method to my django's UserCreationForm for its phone number field. In my current code I am using a get method to retrieve the phone number from its field and then do the validation. If the entered number does not exists, a form error is supposed to pop up and state that the number is not in a country's format (in this case i'm using singapore). Please tell me what changes should be made to my current code.

I've tried using "from phonenumber_field.formfields import PhoneNumberField" for the phone number validation and it validates the number I've entered, the only problem is that the users will have to type their country code and I cannot have that. I'm using just the phonenumbers package so that users will not have to enter the country code.

/* forms.py */
import phonenumbers
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from validate_email import validate_email
from phonenumber_field.formfields import PhoneNumberField


class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()
    # phone_number = PhoneNumberField()
    phone_number = forms.IntegerField(required=True)

    class Meta:
        model = User
        fields = ['username', 'email', 'phone_number']

    def clean_email(self):
        email = self.cleaned_data.get("email")
        if not validate_email(email, verify=True):
            raise forms.ValidationError("Invalid email")
        return email

    def clean_phone(self):
        phone_number = self.cleaned_data.get("phone_number")
        z = phonenumbers.parse(phone_number, "SG")
        if not phonenumbers.is_valid_number(z):
            raise forms.ValidationError("Number not in SG format")
        return phone_number

/* views.py */
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm


def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            # user = form.save()
            # phone_number = form.cleaned_data['phone']
            # do something with phone number??
            user = form.save()
            user.refresh_from_db()
            phone = form.cleaned_data.get('phone_number')
            user.Meta.phone_number = phone
            user.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for {username}!')
            return redirect('blog-home')
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})

I expect the output to validate the entered phone number in the phone field without its country code and only 8 digits and raise an error if that number does not exist.

like image 316
Jackson_Stake Avatar asked Sep 14 '25 13:09

Jackson_Stake


1 Answers

Your validation looks correct to me, but you're doing two things wrong:

  • Rename the method to clean_phone_number() instead of clean_phone. The field is phone_number not phone.
  • Change the field to a CharField instead of IntegerField (too restrictive for many users) and return z.national_number instead of phone_number, that way it's returning the correctly cleaned number before saving. Or whatever format you want to store it in.
like image 61
dirkgroten Avatar answered Sep 17 '25 03:09

dirkgroten