我在模型中存储一个电话号码,就像这样:
phone_number = models.CharField(max_length=12)
用户将输入一个电话号码,我将使用该电话号码进行SMS身份验证。该应用程序将被全局使用。所以我还需要国家代码。CharField是存储电话号码的好方法吗?以及,我如何验证电话号码?
我在模型中存储一个电话号码,就像这样:
phone_number = models.CharField(max_length=12)
用户将输入一个电话号码,我将使用该电话号码进行SMS身份验证。该应用程序将被全局使用。所以我还需要国家代码。CharField是存储电话号码的好方法吗?以及,我如何验证电话号码?
当前回答
实际上,您可以研究国际标准化格式E.164,例如Twilio推荐的格式(Twilio提供了通过REST请求发送短信或电话的服务和API)。
这可能是存储电话号码的最通用方法,特别是如果您使用的是国际号码。
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."))
根据jpotter6,你也可以在你的模型中做以下事情:
文件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
其他回答
使用django-phonenumber-field:
pip install django-phonenumber-field
这个解决方案对我很有效:
首先安装django-phone-field。命令:
pip install django-phone-field
然后在models.py文件中:
from phone_field import PhoneField
...
class Client(models.Model):
...
phone_number = PhoneField(blank=True, help_text='Contact phone number')
在文件settings.py中:
INSTALLED_APPS = [...,
'phone_field'
]
最后是这样的:
首先,用下面的命令安装"django-phonenumber-field"包:
pip install django-phonenumber-field[phonenumbers]
然后,在"settings.py"中将"phonenumber_field"设置为INSTALLED_APPS:
# "settings.py"
INSTALLED_APPS = [
...
"phonenumber_field",
...
]
然后,在"models.py"中使用"PhoneNumberField()"设置一个字段:
# "models.py"
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
class Contact(models.Model):
phone = PhoneNumberField()
然后,在“admin.py”中注册“Contact”:
# "admin.py"
from django.contrib import admin
from .models import Contact
@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
pass
然后,执行如下命令:
python manage.py makemigrations && python manage.py migrate
现在,电话号码字段被创建,如下所示:
此外,将小部件“PhoneNumberPrefixWidget()”分配到自定义表单中的字段,并将自定义表单分配给管理员,如下所示:
# "admin.py"
from django.contrib import admin
from .models import Contact
from django import forms
from phonenumber_field.widgets import PhoneNumberPrefixWidget
class ContactForm(forms.ModelForm):
class Meta:
widgets = {
'phone': PhoneNumberPrefixWidget(),
}
@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
form = ContactForm
现在,使用国家代码创建了电话号码字段
并且,您可以将初始国家代码如initial='US'设置为"PhoneNumberPrefixWidget()",如下所示。*国家代码的首字母必须大写:
# "admin.py"
from django.contrib import admin
from .models import Contact
from django import forms
from phonenumber_field.widgets import PhoneNumberPrefixWidget
class ContactForm(forms.ModelForm):
class Meta:
widgets = { # Here
'phone': PhoneNumberPrefixWidget(initial='US'),
}
@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
form = ContactForm
现在,选择了初始国家代码“US”,创建了电话号码字段:
你也可以在"settings.py"中使用"PHONENUMBER_DEFAULT_REGION"来设置一个初始国家代码,如下所示,但我建议像我上面所做的那样,使用"PHONENUMBER_DEFAULT_REGION"来设置一个初始国家代码为"PhoneNumberPrefixWidget()",因为使用"PHONENUMBER_DEFAULT_REGION"有时不会在Django Admin中显示保存的电话号码:
# "settings.py"
PHONENUMBER_DEFAULT_REGION = "US"
在模型中的phone字段使用CharField,在localflavor应用程序中使用表单验证:
https://docs.djangoproject.com/en/1.7/topics/localflavor/
从2021-12-07开始,LocalFlavor似乎不再是Django的一部分了。
实际上,您可以研究国际标准化格式E.164,例如Twilio推荐的格式(Twilio提供了通过REST请求发送短信或电话的服务和API)。
这可能是存储电话号码的最通用方法,特别是如果您使用的是国际号码。
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."))
根据jpotter6,你也可以在你的模型中做以下事情:
文件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