django 从 CIEmailField 迁移到排序规则

问题描述 投票:0回答:1

我确实将 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"),
            )
        )

因此,当我有用户通过他的电子邮件进行搜索时,我必须在应用程序上的任何地方执行此操作。但应用程序很大。

还有其他解决办法吗?

django collation
1个回答
0
投票

我最终在我的用户模型中使用了

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 之后创建的。

© www.soinside.com 2019 - 2024. All rights reserved.