Reputation: 231
I did upgrade django version to 4.2.8 and then the CIEmailField() is deprecated.
I used this CIEmailField on the email field of an user. So I had to change to:
email = models.EmailField(unique=True, db_collation="case_insensitive")
So the migration is like this:
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),
),
]
But before this changement, with CIEmailField I would .get() an user with this email "[email protected]" or "[email protected]".
With the case_insensitive collation I made it work only by setting "deterministic=False". But with that, the SQL's LIKE is not working. So every Viewset with "email" in "search_fields" wont work.
To make it work, I only found this solution:
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"),
)
)
So I have to do that EVERYWHERE on the App when I have an user to search by his email. But the App is big.
Is there any other solution for this?
Upvotes: 1
Views: 153
Reputation: 23
I ended up using deterministic=True
with custom clean
method in my user model:
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()
You can also use django-citext package, which was created after discussion in mailing list.
Upvotes: 0