Browse Source

chore(api): prepare for Django 4.2

Peter Thomassen 2 years ago
parent
commit
8a76b7ff52

+ 34 - 0
api/desecapi/migrations/0031_alter_user_email.py

@@ -0,0 +1,34 @@
+# Generated by Django 4.1.9 on 2023-06-08 16:40
+
+from django.contrib.postgres.operations import CreateCollation
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("desecapi", "0030_blockedsubnet_blockedsubnet_subnet_idx"),
+    ]
+
+    operations = [
+        # Explanation: https://adamj.eu/tech/2023/02/23/migrate-django-postgresql-ci-fields-case-insensitive-collation/
+        CreateCollation(
+            "case_insensitive",
+            provider="icu",
+            locale="und-u-ks-level2",
+            deterministic=False,
+        ),
+        migrations.AlterField(
+            model_name="user",
+            name="email",
+            field=models.EmailField(
+                db_collation="case_insensitive",
+                max_length=254,
+                unique=True,
+                verbose_name="email address",
+            ),
+        ),
+        migrations.RunSQL(
+            sql='DROP EXTENSION IF EXISTS "citext"',
+            reverse_sql='CREATE EXTENSION IF NOT EXISTS "citext"',
+        ),
+    ]

+ 7 - 2
api/desecapi/models/users.py

@@ -4,7 +4,6 @@ import uuid
 
 from django.conf import settings
 from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
-from django.contrib.postgres.fields import CIEmailField
 from django.core.mail import EmailMessage, get_connection
 from django.db import models
 from django.template.loader import get_template
@@ -35,8 +34,9 @@ class User(ExportModelOperationsMixin("User"), AbstractBaseUser):
         return settings.LIMIT_USER_DOMAIN_COUNT_DEFAULT
 
     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
-    email = CIEmailField(
+    email = models.EmailField(
         verbose_name="email address",
+        db_collation="case_insensitive",  # LIKE queries: LOWER(email COLLATE "und-x-icu") LIKE '%...%'
         unique=True,
     )
     email_verified = models.DateTimeField(null=True, blank=True)
@@ -115,6 +115,11 @@ class User(ExportModelOperationsMixin("User"), AbstractBaseUser):
     def save(self, *args, **kwargs):
         if kwargs.pop("credentials_changed", False):
             self.credentials_changed = timezone.now()
+            # https://docs.djangoproject.com/en/4.2/releases/4.2/#setting-update-fields-in-model-save-may-now-be-required
+            if kwargs.get("update_fields") is not None:
+                kwargs["update_fields"] = {"credentials_changed"}.union(
+                    kwargs["update_fields"]
+                )
         super().save(*args, **kwargs)
 
     def send_email(

+ 1 - 1
api/requirements.txt

@@ -2,7 +2,7 @@ captcha~=0.4.0
 celery~=5.2.7
 coverage~=7.2.7
 cryptography~=41.0.1
-Django~=4.1.0
+Django~=4.1.0  # upgrade once django-pgtrigger is compatible
 django-cors-headers~=4.0.0
 djangorestframework~=3.14.0
 django-celery-email~=3.0.0