Cách tốt nhất để lưu trữ số điện thoại trong các mẫu Django


131

Tôi đang lưu trữ một số điện thoại modelnhư thế này:

phone_number = models.CharField(max_length=12)

Người dùng sẽ nhập số điện thoại và tôi sẽ sử dụng số điện thoại cho SMS AuthenticationỨng dụng này sẽ được sử dụng trên toàn cầu. Vì vậy, tôi cũng sẽ cần mã quốc gia. Là CharFieldmột cách tốt để lưu trữ số điện thoại? Và, làm thế nào để tôi xác nhận số điện thoại?


1
Có một gợi ý tuyệt vời ở đây: stackoverflow.com/a/1245990/207791
Victor Sergienko

Câu trả lời:


283

Bạn thực sự có thể xem xét định dạng chuẩn quốc tế E.164 , được đề xuất bởi Twilio chẳng hạn (người có dịch vụ và API để gửi SMS hoặc cuộc gọi điện thoại qua yêu cầu REST).

Đây có thể là cách phổ biến nhất để lưu trữ số điện thoại, đặc biệt nếu bạn có số quốc tế làm việc cùng.

1. Điện thoại của PhoneNumberField

Bạn có thể sử dụng phonenumber_fieldthư viện. Đây là cổng của thư viện libphonenumber của Google, hỗ trợ xử lý số điện thoại của Android https://github.com/stefanfoulis/django-phonenumber-field

Trong mô hình:

from phonenumber_field.modelfields import PhoneNumberField

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

Thông báo:

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

Lấy điện thoại dưới dạng chuỗi từ trường đối tượng:

    client.phone.as_e164 

Định mức chuỗi điện thoại (để kiểm tra và nhân viên khác):

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

2. Điện thoại bằng regrec

Một lưu ý cho mô hình của bạn: Số E.164 có độ dài ký tự tối đa là 15.

Để xác thực, bạn có thể sử dụng một số kết hợp định dạng và sau đó cố gắng liên hệ với số ngay lập tức để xác minh.

Tôi tin rằng tôi đã sử dụng một cái gì đó như sau trong dự án django của tôi:

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

BIÊN TẬP

Có vẻ như bài đăng này đã hữu ích với một số người, và có vẻ đáng để tích hợp bình luận bên dưới vào một câu trả lời đầy đủ hơn. Theo jpotter6 , bạn cũng có thể làm một số thứ như sau trên các mô hình của mình:

mô hình:

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
Nó có thể có giá trị để chỉ ra cách làm điều này trên một mô hình. phone_regex = RegexValidator (regex = r '^ \ +? 1? \ d {9,15} $', message = "Số điện thoại phải được nhập theo định dạng: '+999999999'. Cho phép tối đa 15 chữ số.") phone_number = model.CharField (xác thực = phone_regex, blank = True)
jpotts18

12
Đừng quên thêm 'max_length = 15' vào các mô hình.CharField
Esteban

4
@Esteban - max_length = 16 (có tùy chọn + khi bắt đầu)
dhackner

3
@erewok - Tôi không tin rằng bạn muốn '1' trong regex của mình. E.164 cho phép tối đa 15 chữ số, bao gồm mã quốc gia.
dhackner 3/2/2015

1
Thật vậy, E.164 không bao gồm bất kỳ tiền tố cuộc gọi quốc tế nào, chỉ có mã quốc gia theo sau là số thực, cũng có độ dài tối thiểu của số E.164 dường như là 8 nên regex nên '^\+\d{8,15}$'và sau đó là max_length=16cho CharField.
Maxime R.

48

Sử dụng django-phonenumber-lĩnh vực: https://github.com/stefanfoulis/django-phonenumber-field

pip install django-phonenumber-field

1
Đừng quên thêm khu vực. Nếu không có PHONENUMBER_DEFAULT_REGION = 'US'trong cài đặt, nó sẽ không cho phép bạn nhập bất cứ thứ gì mà người dùng từ Hoa Kỳ sẽ nhận ra là số điện thoại. Thậm chí sau đó, gói này sẽ không xuất ra dưới dạng số điện thoại. . . Tôi chắc chắn có một thiết lập mà tôi chưa tìm thấy!
Drigan

7
Lưu ý: gói này rất lớn. Trên 40 MB. 33 MB của nó là geodata.
Forethinker

1
Lưu ý nhận xét của @Forethinker, một sự thay thế nhẹ hơn nhiều là github.com/VeryApt/django-phone-field , thông quapip install django-phone-field
SMX

@Forethinker sau đó chúng ta có thể sử dụng phiên bản "lite" pip install django-phonenumber-field[phonenumberslite]không bao gồm siêu dữ liệu mã hóa địa lý, nhà cung cấp và múi giờ
heyjr


3

Xác thực rất dễ dàng, hãy nhắn cho họ một ít mã để nhập. CharField là một cách tuyệt vời để lưu trữ nó. Tôi sẽ không lo lắng quá nhiều về việc đánh số điện thoại.


1

Tất cả phụ thuộc vào những gì bạn hiểu là số điện thoại. Số điện thoại là quốc gia cụ thể. Các gói localflavours cho một số quốc gia chứa "trường số điện thoại" của riêng họ. Vì vậy, nếu bạn ổn theo quốc gia cụ thể, bạn nên xem gói localflavor ( class us.models.PhoneNumberFieldđối với trường hợp ở Hoa Kỳ, v.v.)

Nếu không, bạn có thể kiểm tra các hương vị địa phương để có được chiều dài tối đa cho tất cả các quốc gia. Localflavor cũng có các trường mẫu mà bạn có thể sử dụng cùng với mã quốc gia để xác thực số điện thoại.


Hừm, tôi thấy rằng trong khi tôi làm một nghiên cứu. Bạn có thể đưa ra một ví dụ về cách sử dụng nó trong một hình thức.
pynovice

1

Tôi sẽ mô tả những gì tôi sử dụng:

Xác nhận: chuỗi chứa hơn 5 chữ số.

Dọn dẹp: xóa tất cả các ký hiệu không phải chữ số, viết bằng số db. Tôi may mắn, vì ở nước tôi (Nga) mọi người đều có số điện thoại gồm 10 chữ số. Vì vậy, tôi lưu trữ trong db chỉ 10 diits. Nếu bạn đang viết ứng dụng đa quốc gia, thì bạn nên xác thực toàn diện.

Kết xuất: Tôi viết thẻ mẫu tùy chỉnh để hiển thị nó trong mẫu độc đáo. Hoặc thậm chí kết xuất nó như một bức tranh - sẽ an toàn hơn để ngăn chặn spam sms.


0

Những người khác đề cập django-phonenumber-field. Để có được định dạng hiển thị như thế nào bạn muốn, bạn cần phải thiết lập PHONENUMBER_DEFAULT_FORMATthiết lập để "E164", "INTERNATIONAL", "NATIONAL", hay "RFC3966", tuy nhiên bạn muốn nó hiển thị. Xem nguồn GitHub .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.