diff --git a/src/pretix/base/migrations/0278_login_source_add_unique_together.py b/src/pretix/base/migrations/0278_login_source_add_unique_together.py new file mode 100644 index 0000000000..028c358843 --- /dev/null +++ b/src/pretix/base/migrations/0278_login_source_add_unique_together.py @@ -0,0 +1,41 @@ +# Generated by Django 4.2.16 on 2025-02-28 13:25 + +from django.db import migrations, models + + +def remove_duplicates(apps, schema_editor): + UserKnownLoginSource = apps.get_model("pretixbase", "UserKnownLoginSource") + unique_fields = ["user", "agent_type", "device_type", "os_type", "country"] + + duplicates = ( + UserKnownLoginSource.objects + .values(*unique_fields) + .order_by() + .annotate(latest_id=models.Max('id'), count=models.Count('id')) + .filter(count__gt=1) + ) + + for duplicate in duplicates: + ( + UserKnownLoginSource.objects + .filter(**{x: duplicate[x] for x in unique_fields}) + .exclude(id=duplicate["latest_id"]) + .delete() + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ("pretixbase", "0277_customerssoclient_require_pkce_and_more"), + ] + + operations = [ + migrations.RunPython(remove_duplicates, migrations.RunPython.noop), + migrations.AlterUniqueTogether( + name="userknownloginsource", + unique_together={ + ("user", "agent_type", "device_type", "os_type", "country") + }, + ), + ] diff --git a/src/pretix/base/models/auth.py b/src/pretix/base/models/auth.py index 297316e942..27e0ee6961 100644 --- a/src/pretix/base/models/auth.py +++ b/src/pretix/base/models/auth.py @@ -602,6 +602,9 @@ class UserKnownLoginSource(models.Model): country = FastCountryField(null=True, blank=True) last_seen = models.DateTimeField() + class Meta: + unique_together = ('user', 'agent_type', 'device_type', 'os_type', 'country') + class StaffSession(models.Model): user = models.ForeignKey('User', on_delete=models.PROTECT)