Djangoモデルに電話番号を保存する最良の方法は何ですか


131

私はmodelこのように電話番号を保存しています:

phone_number = models.CharField(max_length=12)

ユーザーは電話番号を入力し、SMS Authenticationこのアプリケーションの電話番号を使用します。このアプリケーションはグローバルに使用されます。したがって、国コードも必要になります。CharField電話番号を保存する良い方法はありますか?また、電話番号を検証するにはどうすればよいですか?


1
ここに素晴らしい提案があります:stackoverflow.com/a/1245990/207791
Victor Sergienko

回答:


283

あなたが実際に国際的に標準化フォーマットに見えるかもしれませんE.164例えばTwilioが推奨します(サービスおよびREST要求を介して、SMSや電話のコールを送信するためのAPIを持っています)。

これは、特に国際電話番号を使用する場合に、電話番号を保存する最も一般的な方法である可能性があります。

1. PhoneNumberFieldによる電話

phonenumber_fieldライブラリを使用できます。これは、Androidの電話番号処理を強化するGoogleのlibphonenumberライブラリのポートです。 ます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

19
モデルでこれを行う方法を示すことも重要です。phone_regex = RegexValidator(regex = r '^ \ +?1?\ d {9,15} $'、message = "電話番号は「+999999999」の形式で入力する必要があります。最大15桁を使用できます。")phone_number = models.CharField(validators = phone_regex、blank = True)
jpotts18

12
models.CharFieldに「= 15 MAX_LENGTH」を追加することを忘れないでください
エステバン

4
@Esteban-max_length = 16(オプションの+が最初にあります)
dhackner

3
@erewok-正規表現に「1」が必要だとは思わない。E.164では、国コードを含めて最大15桁まで使用できます。
dhackner 2015

1
すべての国際電話のプレフィックスが含ま実際、E.164は、唯一の国コードは、実際の数が続いていない、また、164番号の最小長は、正規表現があるべきように、8のようです'^\+\d{8,15}$'し、その後max_length=16のためにCharField
Maxime R.

48

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

pip install django-phonenumber-field

1
地域を追加することを忘れないでください。なけれPHONENUMBER_DEFAULT_REGION = 'US'設定では、電話番号として認識することになる米国から何も入力のユーザーにあなたを許しません。それでも、このパッケージは電話番号のようなものとして出力されません。。。まだ見つけていない設定があるはずです!
ドリガン

7
注:このパッケージは非常に大きいです。40MB以上。33MBは地理データです。
Forethinker

1
@Forethinkerのコメントに注目して、はるかに軽量な代替手段はgithub.com/VeryApt/django-phone-fieldでpip install django-phone-field
SMX

@Forethinker pip install django-phonenumber-field[phonenumberslite]では、ジオコーディング、キャリア、タイムゾーンのメタデータを含まない「ライト」バージョンを使用できます
heyjr


3

検証は簡単で、入力する小さなコードをテキストで送信します。CharFieldは、それを格納するための優れた方法です。電話番号の正規化についてはあまり心配しません。


1

それはすべてあなたが電話番号として理解するものに依存します。電話番号は国によって異なります。いくつかの国のlocalflavorsパッケージには、独自の「電話番号フィールド」が含まれています。したがって、国固有であっても問題ない場合は、localflavorパッケージ(class us.models.PhoneNumberField米国の場合など)。

それ以外の場合は、ローカルフレーバーを検査して、すべての国の最大長を取得できます。Localflavorには、国番号と組み合わせて電話番号を検証するために使用できるフォームフィールドもあります。


ええ、私は研究をしている間にそれを見つけました。フォームでの使用例を教えてください。
pynovice 2013年

1

私が使用するものについて説明します。

検証:文字列に5桁を超える数字が含まれています。

クリーニング:数字以外の記号をすべて削除し、dbのみの数字を書き込みます。私の国(ロシア)では誰もが10桁の電話番号を持っているので、私は幸運です。だから私はdbにたった10のdiitsを保存します。複数の国のアプリケーションを作成している場合は、包括的な検証を行う必要があります。

レンダリング:カスタムテンプレートタグを記述して、テンプレートで適切にレンダリングします。または、画像のようにレンダリングすることもできます-SMSスパムを防ぐ方がより安全です。


0

その他の言及django-phonenumber-field。表示形式を取得するPHONENUMBER_DEFAULT_FORMAT"E164""INTERNATIONAL"、設定を、、、"NATIONAL"またはに設定する必要がありますが、表示する必要があり"RFC3966"ます。GitHubソースを参照しください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.