diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 016df0da513c5d9c7376f3a9c193103222c10b28..4ef4447536ba9422b44e1e91b34223da0aa80b28 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -28,6 +28,7 @@ Fixed * PWA theme colour defaulted to red * Form for editing group type displayed irrelevant fields * Permission groups could get outdated if re-assigning a user account to a different person +* User preferences didn't work correctly sometimes due to race conditions. `2.7`_ - 2022-01-24 ------------------- diff --git a/aleksis/core/migrations/0035_preference_model_unique.py b/aleksis/core/migrations/0035_preference_model_unique.py new file mode 100644 index 0000000000000000000000000000000000000000..0c82528eff8655f356cddb5705623fb5cd4a6120 --- /dev/null +++ b/aleksis/core/migrations/0035_preference_model_unique.py @@ -0,0 +1,55 @@ +# Generated by Django 3.2.11 on 2022-01-27 18:52 + +from email.headerregistry import Group +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sites', '0002_alter_domain_unique'), + ('core', '0034_invite_permission'), + ] + + def _migrate_preference_models_to_unique(apps, schema_editor): + GroupPreferenceModel = apps.get_model("core", "GroupPreferenceModel") + PersonPreferenceModel = apps.get_model("core", "PersonPreferenceModel") + SitePreferenceModel = apps.get_model("core", "SitePreferenceModel") + + from dynamic_preferences import BasePreferenceModel + + models = [GroupPreferenceModel, PersonPreferenceModel, SitePreferenceModel] + + for model in models: + duplicates = {} + db_alias = schema_editor.connection.alias + for obj in model.objects.using(db_alias).all(): + key = f"{obj.instance.pk}__{obj.section}__{obj.name}" + duplicates.setdefault(key, []) + duplicates[key].append(obj) + + for key, objs in duplicates.items(): + if len(objs) > 1: + found = False + for obj in objs: + if BasePreferenceModel.get_value(obj) == BasePreferenceModel.preference(obj).default or found: + obj.delete() + else: + found = True + + + operations = [ + migrations.RunPython(_migrate_preference_models_to_unique), + migrations.AlterUniqueTogether( + name='grouppreferencemodel', + unique_together={('instance', 'section', 'name')}, + ), + migrations.AlterUniqueTogether( + name='personpreferencemodel', + unique_together={('instance', 'section', 'name')}, + ), + migrations.AlterUniqueTogether( + name='sitepreferencemodel', + unique_together={('instance', 'section', 'name')}, + ), + ] diff --git a/aleksis/core/models.py b/aleksis/core/models.py index d5dc7d7befe1395b222ff492f1a9f8eed3994f69..edc92c0fc68a7b495e844cf3f24821eafe2bfc95 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -1082,7 +1082,7 @@ class SitePreferenceModel(PerInstancePreferenceModel, PureDjangoModel): instance = models.ForeignKey(Site, on_delete=models.CASCADE) - class Meta: + class Meta(PerInstancePreferenceModel.Meta): app_label = "core" @@ -1091,7 +1091,7 @@ class PersonPreferenceModel(PerInstancePreferenceModel, PureDjangoModel): instance = models.ForeignKey(Person, on_delete=models.CASCADE) - class Meta: + class Meta(PerInstancePreferenceModel.Meta): app_label = "core" @@ -1100,7 +1100,7 @@ class GroupPreferenceModel(PerInstancePreferenceModel, PureDjangoModel): instance = models.ForeignKey(Group, on_delete=models.CASCADE) - class Meta: + class Meta(PerInstancePreferenceModel.Meta): app_label = "core"