HOWTO · Django

在 Django 中儲存電話號碼的最佳方法

找出在 Django 中儲存電話號碼的幾種方法。

本頁內容

在 Django 模型中處理國際電話號碼時,可使用 django-phonenumber-field 及其 PhoneNumberField;它會根據含有地區資訊的電話號碼中繼資料解析並驗證號碼。如果應用程式只接受範圍狹窄且規則明確的號碼格式,自訂 Django 驗證器可能就足夠。無論採用哪種方式,電話號碼都應以文字而非整數儲存:電話號碼是識別碼,轉換成整數可能會移除開頭的加號或零。

請執行這個範例:

phone_number = "+1 415 555 0132"
print(phone_number)
print(type(phone_number).__name__)
+1 415 555 0132
str

這個範例說明電話號碼為何應儲存在字串欄位中。它不會解析或驗證號碼;如果需要處理國際格式的輸入,請使用下方的套件。

使用第三方 Django 應用程式的 PhoneNumberField 儲存電話號碼

安裝 django-phonenumber-field 時,可選擇搭配較完整的 Python 移植版 phonenumbers,或搭配較輕量的中繼資料套件 phonenumberslite。例如,請在專案環境中執行 python -m pip install "django-phonenumber-field[phonenumbers]"。若要使用 lite 版本,請將 phonenumbers 換成 phonenumberslite。這兩種 extra 是替代選項,請依應用程式所需的中繼資料涵蓋範圍選擇。此專案由 django-phonenumber-field on GitHub 維護,並使用 python-phonenumbers;後者是 Google 的 libphonenumber 的 Python 移植版。

請在 Django 設定的 INSTALLED_APPS 中加入 "phonenumber_field"。接著從 phonenumber_field.modelfields 匯入 PhoneNumberField,並在模型中宣告欄位,例如:phone_number = PhoneNumberField(unique=True)。若號碼欄位可選填,可使用 phone_number = PhoneNumberField(blank=True, null=True)。請一併匯入常用的 from django.db import models,並將這些宣告放在模型類別中。這些範例依賴 Django 執行環境;必須在已設定好的專案中安裝 Django 和此套件,因此並非獨立可執行的範例。

PhoneNumberField 以字串儲存資料,並提供電話號碼物件,可用於解析、驗證及格式化。這些工作彼此相關,但用途不同:解析會根據地區資訊解讀輸入內容,驗證會依據編號計畫的中繼資料檢查號碼,正規化會產生標準表示法,而顯示格式則是為了方便人們閱讀。如果使用者可能輸入國內格式的號碼,請在 Django 設定中選擇預設地區;缺少足夠的地區資訊時,便無法可靠地解讀這類輸入。若要讀取既有記錄中的號碼,可透過模型執行個體存取其值,例如 person.phone_number;需要 E.164 表示法時,則可使用它的 as_e164 屬性。設定和欄位的詳細資訊請參閱專案文件;國際編號計畫則請參閱 E.164。

使用驗證器和 Django 模型儲存電話號碼

如果應用程式只接受有限的號碼格式,而且你能明確定義其規則,Django 的 RegexValidator 可以驗證 CharField。例如,從 django.core.validators 匯入 RegexValidator,定義 phone_number_validator = RegexValidator(regex=r"^\+?1?\d{8,15}$"),再將它傳給模型欄位:phone_number = models.CharField(max_length=16, validators=[phone_number_validator], unique=True)。請將這些宣告放在從 django.db 匯入 models 的模型類別中。這是依賴 Django 的示例,並未作為獨立範例執行。

這個運算式只涵蓋狹窄的格式,包含可選的美國國碼及特定的位數範圍。它不能驗證全球各地的電話號碼、不會檢查號碼是否已分配,也不等同於 PhoneNumberField。只有在這些限制符合應用程式接受的號碼格式時才使用它;否則請採用套件方案,或依據應用程式的實際需求定義驗證器。

E.164 最多允許 15 位數字;國際表示法開頭的 + 是另一個字元。max_length=16 的欄位可以容納這種表示法,但僅設定長度並不能確保符合 E.164 語法或各國的編號規則。驗證器必須檢查允許的前綴和位數;若要進行更完整的國際號碼驗證,則需要編號計畫中繼資料。使用任一種模型欄位時,請依據資料模型決定號碼是否必須唯一,以及欄位是否可以空白或為 null。