【问题标题】:What's the best way to store a phone number in Django models?在 Django 模型中存储电话号码的最佳方法是什么
【发布时间】:2013-10-08 11:36:52
【问题描述】:

我在model 中存储了一个电话号码,如下所示:

phone_number = models.CharField(max_length=12)

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

【问题讨论】:

标签: django django-forms django-validation


【解决方案1】:

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

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

【讨论】:

  • 嗯,是的,我在研究时发现了这一点。能否举例说明如何在表单中使用它。
【解决方案2】:

我将描述我使用的东西:

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

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

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

【讨论】:

    【解决方案3】:

    验证很简单,只需给他们输入一些代码即可。 CharField 是存储它的好方法。我不会太担心电话号码的规范化。

    【讨论】:

      【解决方案4】:

      您实际上可能会研究国际标准化格式E.164recommended by Twilio for example(它们具有通过 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,您也可以在您的模型上执行以下操作:

      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
      

      【讨论】:

      • 展示如何在模型上执行此操作可能很有价值。 phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="必须输入以下格式的电话号码:'+999999999'。最多允许 15 位数字。") phone_number = models.CharField(validators=phone_regex, blank=True)
      • 不要忘记在 models.CharField 中添加 'max_length=15'
      • @Esteban - max_length=16(开头有一个可选的 +)
      • @erewok - 我不相信你想要你的正则表达式中的“1”。 E.164 最多允许 15 位数字,包括国家代码。
      • 确实,E.164 不包括任何国际电话前缀,只有国家代码后跟实际号码,minimum length of an E.164 number 似乎是 8 所以正则表达式应该是 '^\+\d{8,15}$' 然后max_length=16CharField
      【解决方案5】:

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

      pip install django-phonenumber-field
      

      【讨论】:

      • 不要忘记添加区域。如果在设置中没有PHONENUMBER_DEFAULT_REGION = 'US',它将不允许您输入任何来自美国的用户会识别为电话号码的内容。即使这样,这个包也不会像电话号码一样输出。 . .我确定有一个我还没找到的设置!
      • 注意:这个包很大。超过 40MB。其中 33MB 是地理数据。
      • 注意到@Forethinker 的评论,一个更轻量级的替代方案是github.com/VeryApt/django-phone-field,通过pip install django-phone-field
      • @Forethinker 然后我们可以使用不包括地理编码、运营商和时区元数据的“精简版”pip install django-phonenumber-field[phonenumberslite]
      【解决方案6】:

      使用CharField 作为模型中的电话字段,使用localflavor 应用进行表单验证:

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

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

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

      【讨论】:

      • 我现在同意@rgenito(对于 Django 3.x),我目前正在使用django-phonenumber-field(和phonenumbers)。
      • 链接已损坏。
      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

        这个解决方案对我有用:

        首先安装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'
        ]
        

        最后是这样的

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-16
          • 1970-01-01
          • 1970-01-01
          • 2012-10-31
          • 1970-01-01
          • 2010-11-09
          相关资源
          最近更新 更多