From 46cee890f03e8a5aa991bf7b6af92e8c767d71d3 Mon Sep 17 00:00:00 2001 From: Richard Schreiber Date: Mon, 15 Mar 2021 15:34:33 +0100 Subject: [PATCH] QuestionAnswer: Add UNIQUE keys on (orderposition, question) and (cartposition, question) (#1994) --- .../migrations/0179_auto_20210311_1653.py | 49 +++++++++++++++++++ src/pretix/base/models/orders.py | 3 ++ 2 files changed, 52 insertions(+) create mode 100644 src/pretix/base/migrations/0179_auto_20210311_1653.py diff --git a/src/pretix/base/migrations/0179_auto_20210311_1653.py b/src/pretix/base/migrations/0179_auto_20210311_1653.py new file mode 100644 index 0000000000..9e45392a11 --- /dev/null +++ b/src/pretix/base/migrations/0179_auto_20210311_1653.py @@ -0,0 +1,49 @@ +# Generated by Django 3.0.10 on 2021-03-11 16:53 + +from django.db import migrations + + +def clean_duplicates(apps, schema_editor): + while True: + delete_options = """ + DELETE + FROM pretixbase_questionanswer_options + WHERE questionanswer_id IN ( + SELECT MIN(qa.id) + FROM pretixbase_questionanswer qa + GROUP BY qa.cartposition_id, qa.orderposition_id, qa.question_id + HAVING COUNT(*) > 1 + ); + """ + delete_answers = """ + DELETE + FROM pretixbase_questionanswer + WHERE pretixbase_questionanswer.id IN ( + SELECT MIN(qa.id) + FROM pretixbase_questionanswer qa + GROUP BY qa.cartposition_id, qa.orderposition_id, qa.question_id + HAVING COUNT(*) > 1 + ); + """ + with schema_editor.connection.cursor() as cursor: + cursor.execute(delete_options) + cursor.execute(delete_answers) + if cursor.rowcount == 0: + return + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0178_auto_20210308_1326'), + ] + + operations = [ + migrations.RunPython( + clean_duplicates, + migrations.RunPython.noop, + ), + migrations.AlterUniqueTogether( + name='questionanswer', + unique_together={('orderposition', 'question'), ('cartposition', 'question')}, + ), + ] diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 577a3d8d50..509d4fce33 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -983,6 +983,9 @@ class QuestionAnswer(models.Model): objects = ScopedManager(organizer='question__event__organizer') + class Meta: + unique_together = [['orderposition', 'question'], ['cartposition', 'question']] + @property def backend_file_url(self): if self.file: