185

我正在model像这样存储一个电话号码:

phone_number = models.CharField(max_length=12)

用户将输入一个电话号码,我将使用该电话号码SMS Authentication此应用程序将在全球范围内使用。所以我还需要国家代码。是CharField存储电话号码的好方法吗?还有,我如何验证电话号码?

4

9 回答 9

372

您实际上可能会研究国际标准化格式E.164例如 Twilio 推荐的(他们有通过 REST 请求发送 SMS 或电话的服务和 API)。

这可能是最通用的电话号码存储方式,尤其是在您使用国际号码的情况下。

1. 按PhoneNumberField 拨打电话

你可以使用phonenumber_field图书馆。它是 Google 的 libphonenumber 库的端口,它支持 Android 的电话号码处理 https://github.com/stefanfoulis/django-phonenumber-field

在模型中:

from phonenumber_field.modelfields import PhoneNumberField

class Client(models.Model, Importable):
    phone = PhoneNumberField(null=False, blank=False, unique=True)

通知:

from phonenumber_field.formfields import PhoneNumberField
class ClientForm(forms.Form):
    phone = PhoneNumberField()

从对象字段中获取电话作为字符串:

    client.phone.as_e164 

标准化电话字符串(用于测试和其他工作人员):

    from phonenumber_field.phonenumber import PhoneNumber
    phone = PhoneNumber.from_string(phone_number=raw_phone, region='RU').as_e164

2.通过正则表达式电话

您的模型的一个注意事项:E.164 数字的最大字符长度为 15。

要进行验证,您可以使用某种格式组合,然后尝试立即联系该号码进行验证。

我相信我在我的 django 项目中使用了以下内容:

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 allowed."))

编辑

看来这篇文章对某些人很有用,将下面的评论整合到更完整的答案中似乎是值得的。根据jpotter6,您也可以在模型上执行以下操作:

模型.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
于 2013-10-02T06:49:01.273 回答
61

使用 django-phonenumber-field: https ://github.com/stefanfoulis/django-phonenumber-field

pip install django-phonenumber-field
于 2014-03-19T06:02:14.967 回答
8

用于CharField模型中的电话字段和localflavor应用程序进行表单验证:

https://docs.djangoproject.com/en/1.7/topics/localflavor/

更新(29021-12-07)。看起来 LocalFlavor 不再是 Django 的一部分:

https://pypi.org/project/django-localflavor/

于 2014-12-17T20:34:32.260 回答
6

这个解决方案对我有用:

首先安装 django-phone-field

command: 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'
]

最后看起来是这样的

电话形式

于 2020-10-29T01:50:11.787 回答
5

验证很容易,给他们输入一些代码来输入。 CharField 是存储它的好方法。我不会太担心规范化电话号码。

于 2013-10-02T06:34:39.523 回答
1

我将描述我使用的内容:

验证:字符串包含超过 5 位数字。

清理:删除所有非数字符号,仅写入 db 数字。我很幸运,因为在我的国家(俄罗斯),每个人都有 10 位数字的电话号码。所以我只在 db 中存储 10 个 diits。如果您正在编写多国应用程序,那么您应该进行全面验证。

渲染:我编写自定义模板标签以很好地在模板中渲染它。甚至将其渲染为图片 - 防止垃圾短信更安全。

于 2013-10-02T06:25:32.400 回答
1

这完全取决于您对电话号码的理解。电话号码是特定国家/地区的。几个国家/地区的 localflavors 包包含自己的“电话号码字段”。因此,如果您可以确定特定国家/地区,则应查看 localflavor 包(class us.models.PhoneNumberField对于美国案例等)

否则,您可以检查当地风味以获得所有国家/地区的最大长度。Localflavor 还具有表单字段,您可以将其与国家代码结合使用来验证电话号码。

于 2013-10-02T06:24:49.933 回答
1

首先,你需要安装手机号django包。

pip install django-phonenumber-field[phonenumbers]

然后下一步是将其添加到已安装的应用程序中

INSTALLED_APPS = [
    ...
    'phonenumber_field',
    ...
]

这是如何在您的模型中使用它

from phonenumber_field.modelfields import PhoneNumberField

class Artist(models.Model):
   
     phone_number = PhoneNumberField()
于 2022-02-09T03:41:21.113 回答
1

其他人提到django-phonenumber-field。要获得所需的显示格式,您需要将设置PHONENUMBER_DEFAULT_FORMAT设置为"E164""INTERNATIONAL""NATIONAL""RFC3966",但是您希望它显示。请参阅GitHub 源代码

于 2019-11-01T03:14:45.687 回答