2024-09-08

Django 4.2 之後棄用 PostgreSQL 的 CIText 類欄位的因應做法

參考文件

核心做法

  • 在 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。