问题
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.
回答1:
Your validation looks correct to me, but you're doing two things wrong:
- Rename the method to
clean_phone_number()
instead ofclean_phone
. The field isphone_number
notphone
. - Change the field to a
CharField
instead ofIntegerField
(too restrictive for many users) andreturn z.national_number
instead ofphone_number
, that way it's returning the correctly cleaned number before saving. Or whatever format you want to store it in.
回答2:
I am not entirely familiar with these packages but after having a look at the repo code behind them it seems like you could just set the region
attribute on the PhoneNumberField
and keep inheriting all of its validation features and prevent the need for users to type in their region?
Something like this?
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
来源:https://stackoverflow.com/questions/58006706/how-to-validate-phone-number-in-django