我确实将 django 版本升级到 4.2.8,然后 CIEmailField() 被弃用。
我在用户的电子邮件字段上使用了此 CIEmailField。所以我不得不改为:
email = models.EmailField(unique=True, db_collation="case_insensitive")
所以迁移是这样的:
operations = [
CreateCollation(
"case_insensitive",
provider="icu",
locale="und-u-ks-level2",
deterministic=True,
),
migrations.AlterField(
model_name="user",
name="email",
field=models.EmailField(db_collation="case_insensitive", max_length=254),
),
]
但在此更改之前,使用 CIEmailField 我会 .get() 具有此电子邮件地址“[email protected]”或“[email protected]”的用户。
对于不区分大小写的排序规则,我仅通过设置“确定性=假”使其工作。但这样一来,SQL 的 LIKE 就不起作用了。因此,“search_fields”中带有“email”的每个视图集都不起作用。
为了使其工作,我只找到了这个解决方案:
class UserAdmin(BaseUserAdmin):
search_fields = ("email_deterministic", ...)
...
def get_queryset(self, request: HttpRequest) -> QuerySet[User]:
return (
super()
.get_queryset(request)
.annotate(
email_deterministic=Collate("email", "und-x-icu"),
)
)
因此,当我有用户通过他的电子邮件进行搜索时,我必须在应用程序上的任何地方执行此操作。但应用程序很大。
还有其他解决办法吗?
我最终在我的用户模型中使用了
deterministic=True
和自定义 clean
方法:
class User(AbstractBaseUser):
email = models.EmailField(
unique=True,
db_collation="case_insensitive",
)
# ...
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
def clean(self):
super().clean()
self.email = self.__class__.objects.normalize_email(self.email).lower()
您还可以使用 django-citext 包,该包是在邮件列表中的 discussion 之后创建的。