diff --git a/oioioi/problems/migrations/0039_alter_algorithmtagproposal_unique_together_and_more.py b/oioioi/problems/migrations/0039_alter_algorithmtagproposal_unique_together_and_more.py new file mode 100644 index 000000000..1a0478c8d --- /dev/null +++ b/oioioi/problems/migrations/0039_alter_algorithmtagproposal_unique_together_and_more.py @@ -0,0 +1,64 @@ +# Generated by Django 5.2.7 on 2025-11-17 22:44 + +from django.conf import settings +from django.db import migrations +from django.db.models import Count + +def cleanup_duplicate_proposals(apps, schema_editor): + AlgorithmTagProposal = apps.get_model('problems', 'AlgorithmTagProposal') + DifficultyTagProposal = apps.get_model('problems', 'DifficultyTagProposal') + + # Cleanup AlgorithmTagProposal + duplicates = ( + AlgorithmTagProposal.objects.values('problem', 'tag', 'user') + .annotate(count=Count('id')) + .filter(count__gt=1) + ) + + for duplicate in duplicates: + proposals = AlgorithmTagProposal.objects.filter( + problem=duplicate['problem'], + tag=duplicate['tag'], + user=duplicate['user'] + ).order_by('id') + + # Keep the first one, delete the rest + for proposal in proposals[1:]: + proposal.delete() + + # Cleanup DifficultyTagProposal + duplicates = ( + DifficultyTagProposal.objects.values('problem', 'user') + .annotate(count=Count('id')) + .filter(count__gt=1) + ) + + for duplicate in duplicates: + proposals = DifficultyTagProposal.objects.filter( + problem=duplicate['problem'], + user=duplicate['user'] + ).order_by('id') + + # Keep the first one, delete the rest + for proposal in proposals[1:]: + proposal.delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('problems', '0038_alter_algorithmtaglocalization_language_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RunPython(cleanup_duplicate_proposals), + migrations.AlterUniqueTogether( + name='algorithmtagproposal', + unique_together={('problem', 'tag', 'user')}, + ), + migrations.AlterUniqueTogether( + name='difficultytagproposal', + unique_together={('problem', 'user')}, + ), + ] diff --git a/oioioi/problems/models.py b/oioioi/problems/models.py index e38c740fe..e78511f90 100644 --- a/oioioi/problems/models.py +++ b/oioioi/problems/models.py @@ -797,6 +797,7 @@ def __str__(self): return str(self.problem.name) + " -- " + str(self.tag.name) class Meta: + unique_together = ("problem", "user") verbose_name = _("difficulty proposal") verbose_name_plural = _("difficulty proposals") @@ -878,6 +879,7 @@ def __str__(self): return str(self.problem.name) + " -- " + str(self.tag.name) class Meta: + unique_together = ("problem", "tag", "user") verbose_name = _("algorithm tag proposal") verbose_name_plural = _("algorithm tag proposals")