如何在Django中验证电话号码?

时间:2019-09-19 08:22:20

标签: python django validation phone-number

我目前正在使用phonenumbers软件包作为django的UserCreationForm的电话号码字段的验证方法。在当前代码中,我正在使用get方法从其字段中检索电话号码,然后进行验证。如果输入的号码不存在,则应该弹出表格错误,并指出该号码不是国家/地区格式(在这种情况下,我使用的是新加坡)。请告诉我应该对当前代码进行哪些更改。

我尝试使用“ from phonenumber_field.formfields import PhoneNumberField”进行电话号码验证,它可以验证我输入的号码,唯一的问题是用户将不得不输入其国家代码,而我不能输入。我只使用电话号码包,这样用户就不必输入国家/地区代码。

/* 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})

我希望输出能够验证电话字段中输入的电话号码(不含国家/地区代码,只需输入8位数字),如果该号码不存在,则会引发错误。

2 个答案:

答案 0 :(得分:0)

您的验证对我来说似乎是正确的,但是您做错了两件事:

  • 将方法重命名为clean_phone_number(),而不是clean_phone。该字段是phone_number而不是phone
  • 将字段更改为CharField而不是IntegerField(对许多用户来说太严格了),将字段更改为return z.national_number而不是phone_number,这样它将在返回之前正确地清除数字保存。或您想要存储的任何格式。

答案 1 :(得分:0)

我对这些软件包并不完全熟悉,但是在查看了它们背后的回购代码之后,似乎可以在region上设置PhoneNumberField属性,并继续继承其所有验证功能,并防止用户在其区域中键入文字?

像这样吗?


class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()
    # Does this not work for your case?
    phone_number = PhoneNumberField(region="SG")

    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