Is case-insensitive uniquness in PostgeSQL not possible with Django 5.2.7?

I noticed I cannot use the Postgres CIEmailField and CICharField anymore so I tried to create a case-insensitive db collation and use that in its place but then I got an error that the case insensitive db collation cannot be used on fields that have unique=True. What I’ve done as a work-around is to remove the unique=True constraint, leave the case insensitive db_collation attribute, and implement uniqueness at the application level by overriding the save() method. But this doesn’t account bulk_create() and update() as those do not use the save() method. Am I missing something or is there a better way?

The discussion around this change and some talk about alternative methods can be found at:

Superficially, my personal inclination would be to create a generated field as described at https://groups.google.com/g/django-developers/c/nDMnO98nexY/m/4fhLtlR7AwAJ - but that’s an off-the-cuff reaction to what I’m reading with no real thought behind it.

1 Like

I ended up taking your advice and creating a second field (generated) that compares the referenced field in lower case to existing values so it has the same result as case-insensitive uniqueness in the end.

email = models.EmailField(max_length=128, unique=True)
email_lower = models.GeneratedField(
expression=Lower(“email”),
output_field=models.EmailField(),
db_persist=True,
unique=True,
)