Telefon numarasını Django modellerinde saklamanın en iyi yolu nedir


132

Şu şekilde bir telefon numarası saklıyorum model:

phone_number = models.CharField(max_length=12)

Kullanıcı bir telefon numarası girer ve SMS Authenticationbu uygulama için telefon numarasını kullanırdım Bu uygulama global olarak kullanılır. Bu yüzden ülke koduna da ihtiyacım olacak. Mı CharFieldtelefon numarasını saklamak için iyi bir yoldur? Ve telefon numarasını nasıl doğrularım?


1
Burada harika bir öneri var: stackoverflow.com/a/1245990/207791
Victor Sergienko

Yanıtlar:


285

Aslında uluslararası standart formatı içine görünebilir E. 164 , örneğin Twilio tarafından önerilen (bir hizmeti ve DİNLENME istekleri üzerinden SMS ya da telefon-çağrıları göndermek için bir API var).

Bu, özellikle birlikte çalıştığınız uluslararası numaralarınız varsa, telefon numaralarını saklamanın en evrensel yolu olabilir.

1. PhoneNumberField ile Telefon

phonenumber_fieldKitaplığı kullanabilirsiniz . Google'ın libphonenumber kitaplığının limanıdır ve Android'in telefon numarası işleme https://github.com/stefanfoulis/django-phonenumber-field

Modelde:

from phonenumber_field.modelfields import PhoneNumberField

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

Bilgi vermek:

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

Telefonu nesne alanından dizge olarak alın:

    client.phone.as_e164 

Normolize telefon dizisi (testler ve diğer personel için):

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

2. regexp ile telefon

Modeliniz için bir not: E.164 numaralarının maksimum karakter uzunluğu 15'tir.

Doğrulamak için, bazı biçimlendirme kombinasyonlarını kullanabilir ve ardından doğrulamak için hemen numarayla iletişime geçmeyi deneyebilirsiniz.

Django projemde aşağıdakine benzer bir şey kullandığıma inanıyorum:

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

DÜZENLE

Bu yazının bazı insanlar için faydalı olduğu anlaşılıyor ve aşağıdaki yorumu daha eksiksiz bir cevaba entegre etmeye değer görünüyor. Gereğince jpotter6 , siz de modellerde aşağıdaki gibi bir şey yapabilirsiniz:

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
Bunun bir model üzerinde nasıl yapılacağını göstermek de değerli olabilir. phone_regex = RegexValidator (regex = r '^ \ +? 1? \ d {9,15} $', message = "Telefon numarası '+999999999' biçiminde girilmelidir. 15 haneye kadar izin verilir.") telefon_numarası = models.CharField (doğrulayıcılar = phone_regex, blank = True)
jpotts18

12
Modellere 'max_length = 15' eklemeyi unutmayın.CharField
Esteban

4
@Esteban - max_length = 16 (başlangıçta isteğe bağlı bir + vardır)
dhackner

3
@erewok - Normal ifadende '1'i istediğine inanmıyorum. E.164, ülke kodu dahil 15 haneye kadar izin verir.
dhackner

1
Nitekim, E.164 herhangi bir uluslararası arama önekleri, gerçek sayı ile takip tek ülke kodunu içermez, aynı zamanda bir E. 164 sayısının minimum uzunluğu regex olmalıdır böylece 8 gibi görünüyor '^\+\d{8,15}$'sonra ve max_length=16için CharField.
Maxime R.

48

Django-telefon numarası-alanını kullanın: https://github.com/stefanfoulis/django-phonenumber-field

pip install django-phonenumber-field

1
Bölgeyi eklemeyi unutmayın. PHONENUMBER_DEFAULT_REGION = 'US'Ayarlar olmadan , Amerika Birleşik Devletleri'ndeki kullanıcıların telefon numarası olarak tanıyacağı herhangi bir şeyi girmenize izin vermez. O zaman bile, bu paket bir telefon numarasına benzeyen bir şey çıkmaz. . . Eminim henüz bulamadığım bir ayar vardır!
Drigan

7
Not: Bu paket çok büyük. 40 MB'ın üzerinde. 33 MB'si coğrafi veridir.
Forethinker

1
@Forethinker'ın yorumuna dikkat çekerek, çok daha hafif bir alternatif github.com/VeryApt/django-phone-field , viapip install django-phone-field
SMX

@Forethinker daha sonra pip install django-phonenumber-field[phonenumberslite]coğrafi kodlama, operatör ve saat dilimi meta verilerini içermeyen "lite" sürümünü kullanabiliriz
heyjr


3

Doğrulama kolaydır, onlara yazmaları için küçük bir kod yazın. CharField, depolamanın harika bir yoludur. Telefon numaralarını standart hale getirme konusunda fazla endişelenmem.


1

Her şey, telefon numarası olarak ne anladığınıza bağlıdır. Telefon numaraları ülkeye özeldir. Birkaç ülke için yerel tatlar paketleri kendi "telefon numarası alanını" içerir. Bu nedenle, ülkeye özgü olma konusunda sorun yaşamıyorsanız, yerel lezzet paketine bir göz atmalısınız ( class us.models.PhoneNumberFieldABD davası vb.)

Aksi takdirde, tüm ülkeler için maksimum uzunluğu elde etmek için yerel lezzetleri inceleyebilirsiniz. Localflavor ayrıca telefon numarasını doğrulamak için ülke koduyla birlikte kullanabileceğiniz form alanlarına sahiptir.


Hm Evet, bunu araştırma yaparken buldum. Bir formda nasıl kullanılacağına dair bir örnek verebilir misiniz?
pynovice

1

Ne kullandığımı açıklayacağım:

Doğrulama: dize 5'ten fazla rakam içeriyor.

Temizleme: rakam olmayan tüm sembolleri kaldırın, sadece db ile yazın. Şanslıyım çünkü benim ülkemde (Rusya) herkesin 10 haneli telefon numaraları var. Bu yüzden db'de sadece 10 diit depoluyorum. Çok ülkeli bir başvuru yazıyorsanız, kapsamlı bir doğrulama yapmanız gerekir.

Rendering: Şablonda güzelce işlemek için özel şablon etiketi yazıyorum. Ya da bir resim gibi sunun - sms spam'lerini önlemek daha güvenlidir.


0

Diğerleri bahsedildi django-phonenumber-field. Eğer set gerekir istiyorum nasıl görüntüleme biçimini elde etmek PHONENUMBER_DEFAULT_FORMATiçin ayarı "E164", "INTERNATIONAL", "NATIONAL"veya "RFC3966", ancak bunu görüntülenen istiyorum. GitHub kaynağına bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.