วิธีใดเป็นวิธีที่ดีที่สุดในการจัดเก็บหมายเลขโทรศัพท์ในโมเดล Django


133

ฉันกำลังจัดเก็บหมายเลขโทรศัพท์ในmodelลักษณะนี้:

phone_number = models.CharField(max_length=12)

ผู้ใช้จะต้องป้อนหมายเลขโทรศัพท์และฉันจะใช้หมายเลขโทรศัพท์สำหรับSMS Authenticationแอปพลิเคชันนี้จะใช้ทั่วโลก ดังนั้นฉันต้องใช้รหัสประเทศด้วย เป็นCharFieldวิธีที่ดีในการจัดเก็บหมายเลขโทรศัพท์? และฉันจะตรวจสอบหมายเลขโทรศัพท์ได้อย่างไร?


1
มีข้อเสนอแนะดีๆที่นี่: stackoverflow.com/a/1245990/207791
Victor Sergienko

คำตอบ:


289

คุณอาจดูรูปแบบE.164 ที่เป็นมาตรฐานสากลซึ่งTwilio แนะนำ (ผู้ที่มีบริการและ API สำหรับส่ง SMS หรือโทรศัพท์ผ่านคำขอ REST)

นี่เป็นวิธีที่เป็นสากลที่สุดในการจัดเก็บหมายเลขโทรศัพท์โดยเฉพาะอย่างยิ่งหากคุณมีหมายเลขระหว่างประเทศที่ใช้งานได้

1. โทรศัพท์โดย PhoneNumberField

คุณสามารถใช้phonenumber_fieldไลบรารี เป็นพอร์ตของไลบรารี libphonenumber ของ Google ซึ่งช่วยในการจัดการหมายเลขโทรศัพท์ของ 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 

Normolize สายโทรศัพท์ (สำหรับการทดสอบและเจ้าหน้าที่อื่น ๆ ):

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

2. โทรศัพท์โดย regexp

หมายเหตุสำหรับรุ่นของคุณ: หมายเลข 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
อย่าลืมเพิ่ม 'max_length = 15' ให้กับโมเดล CharField
Esteban

4
@Esteban - max_length = 16 (มีตัวเลือก + ในตอนเริ่มต้น)
dhackner

3
@erewok - ฉันไม่เชื่อว่าคุณต้องการ '1' ใน regex ของคุณ E.164 อนุญาตได้สูงสุด 15 หลักรวมรหัสประเทศ
dhackner

1
อันที่จริง E.164 ไม่รวมคำนำหน้าการโทรระหว่างประเทศใด ๆ มีเพียงรหัสประเทศตามด้วยหมายเลขจริงความยาวขั้นต่ำของหมายเลข E.164ดูเหมือนจะเป็น 8 ดังนั้น regex จึงควรเป็น'^\+\d{8,15}$'แล้วmax_length=16สำหรับCharField.
Maxime R.

49

ใช้ django-phonenumber-field: https://github.com/stefanfoulis/django-phonenumber-field

pip install django-phonenumber-field

1
อย่าลืมเพิ่มภูมิภาค หากไม่มีPHONENUMBER_DEFAULT_REGION = 'US'การตั้งค่าจะไม่อนุญาตให้คุณป้อนข้อมูลใด ๆ ที่ผู้ใช้จากสหรัฐอเมริกาจะรับรู้ว่าเป็นหมายเลขโทรศัพท์ ถึงกระนั้นแพ็คเกจนี้จะไม่แสดงผลเป็นหมายเลขโทรศัพท์ . . ฉันแน่ใจว่ามีการตั้งค่าที่ฉันยังไม่พบ!
Drigan

7
หมายเหตุ: แพ็คเกจนี้ใหญ่มาก มากกว่า 40MB. 33MB คือ geodata
Forethinker

1
สังเกตความคิดเห็นของ @Forethinker ทางเลือกที่มีน้ำหนักเบากว่ามากคือgithub.com/VeryApt/django-phone-fieldผ่านpip install django-phone-field
SMX

@Forethinker เราสามารถใช้เวอร์ชัน "lite" pip install django-phonenumber-field[phonenumberslite]ซึ่งไม่รวมข้อมูลเมตาของ geocoding ผู้ให้บริการและเขตเวลา
heyjr


3

การตรวจสอบความถูกต้องเป็นเรื่องง่ายเพียงแค่พิมพ์รหัสให้พวกเขาพิมพ์ CharField เป็นวิธีที่ดีในการจัดเก็บ ฉันจะไม่กังวลมากเกินไปเกี่ยวกับการกำหนดหมายเลขโทรศัพท์ตามรูปแบบบัญญัติ


1

ทั้งหมดขึ้นอยู่กับสิ่งที่คุณเข้าใจว่าเป็นหมายเลขโทรศัพท์ หมายเลขโทรศัพท์เป็นหมายเลขเฉพาะประเทศ แพ็คเกจ localflavors สำหรับหลายประเทศมี "ช่องหมายเลขโทรศัพท์" เป็นของตัวเอง ดังนั้นหากคุณตกลงเป็นเฉพาะประเทศคุณควรดูแพ็คเกจ localflavour ( class us.models.PhoneNumberFieldสำหรับกรณีในสหรัฐอเมริกา ฯลฯ )

มิฉะนั้นคุณสามารถตรวจสอบรสชาติท้องถิ่นเพื่อให้ได้ความยาวสูงสุดสำหรับทุกประเทศ Localflavour ยังมีช่องแบบฟอร์มที่คุณสามารถใช้ร่วมกับรหัสประเทศเพื่อตรวจสอบหมายเลขโทรศัพท์


อืมใช่ฉันพบว่าในขณะที่ฉันทำการวิจัย คุณสามารถยกตัวอย่างวิธีการใช้งานในรูปแบบ.
pynovice

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.