參考文件
- Adam Johnson - How to migrate from Django’s PostgreSQL CI Fields to use a case-insensitive collation
- Django Document: CICharField
- Django Document: Managing collations using migrations
- PostgreSQL Support Collation
- What is Collation in Database? 什麼是資料庫中的排序規則?
核心做法
- 在 migrations 的 operations 建立名為 case_insensitive 的 db_collation,參考文件中的 locale 是設定為 “und-u-ks-level2”,我改成 “zh-TW-u-ks-level2”,以後有問題再改回來。
from django.contrib.postgres.operations import CreateCollation operations = [ CreateCollation( "case_insensitive", provider="icu", locale="zh-TW-u-ks-level2", deterministic=False, ), migrations.CreateModel( name="MyUser", fields=[ ... ( "email", models.EmailField( db_collation="case_insensitive", max_length=254, unique=True, validators=[ django.core.validators.EmailValidator( message="請輸入有效的E-mail信箱" ) ], verbose_name="電子信箱", ), ), ... ] ) ]
-
在 models.py 中需要不分大小寫的欄位,指定 db_collation 為前面建立的 collation,db_collation=”case_insensitive”
class MyUser(AbstractUser): email = models.EmailField( _("電子信箱"), db_collation="case_insensitive", unique=True, validators=[EmailValidator(message="請輸入有效的E-mail信箱")], )
遇到的狀況或修正
- 我的系統在建立使用者後,會透過 signal 建立其他的 model,而建立其他 model 時又需要讀取資料庫中其他 model 的值。所以測試過程使用 setUp() method 先建立需要的 model 的值。
- 依據第1篇參考文件的說明,我把 language tag 由 und 改成 zh-TW。