forked from CGM_Public/pretix_original
Ensure uniqueness of question identifiers (#2358)
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 3.2.4 on 2021-12-01 11:55
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db.models import Count
|
||||||
|
|
||||||
|
|
||||||
|
def change_unique_identifiers(apps, schema_editor):
|
||||||
|
# We cannot really know if a position was bundled or an add-on, but we can at least guess
|
||||||
|
Question = apps.get_model("pretixbase", "Question")
|
||||||
|
|
||||||
|
for r in Question.objects.values('event', 'identifier').order_by().annotate(c=Count('*')).filter(c__gt=1):
|
||||||
|
qs = Question.objects.filter(identifier=r['identifier'], event_id=r['event'])
|
||||||
|
for i, q in enumerate(qs[1:]):
|
||||||
|
q.identifier += f'_{i + 2}'
|
||||||
|
q.save(update_fields=['identifier'])
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('pretixbase', '0220_auto_20220811_1002'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(
|
||||||
|
change_unique_identifiers,
|
||||||
|
migrations.RunPython.noop,
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 3.2.4 on 2021-12-01 12:04
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pretixbase', '0221_clean_nonunique_question_identifiers'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='question',
|
||||||
|
unique_together={('event', 'identifier')},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1329,6 +1329,7 @@ class Question(LoggedModel):
|
|||||||
verbose_name = _("Question")
|
verbose_name = _("Question")
|
||||||
verbose_name_plural = _("Questions")
|
verbose_name_plural = _("Questions")
|
||||||
ordering = ('position', 'id')
|
ordering = ('position', 'id')
|
||||||
|
unique_together = (('event', 'identifier'),)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.question)
|
return str(self.question)
|
||||||
@@ -1344,7 +1345,7 @@ class Question(LoggedModel):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _clean_identifier(event, code, instance=None):
|
def _clean_identifier(event, code, instance=None):
|
||||||
qs = Question.objects.filter(event=event, identifier__iexact=code)
|
qs = Question.objects.filter(event=event, identifier__iexact=code)
|
||||||
if instance:
|
if instance and instance.pk:
|
||||||
qs = qs.exclude(pk=instance.pk)
|
qs = qs.exclude(pk=instance.pk)
|
||||||
if qs.exists():
|
if qs.exists():
|
||||||
raise ValidationError(_('This identifier is already used for a different question.'))
|
raise ValidationError(_('This identifier is already used for a different question.'))
|
||||||
|
|||||||
@@ -129,6 +129,11 @@ class QuestionForm(I18nModelForm):
|
|||||||
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
def clean_identifier(self):
|
||||||
|
val = self.cleaned_data.get('identifier')
|
||||||
|
Question._clean_identifier(self.instance.event, val, self.instance)
|
||||||
|
return val
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
d = super().clean()
|
d = super().clean()
|
||||||
if d.get('dependency_question') and not d.get('dependency_values'):
|
if d.get('dependency_question') and not d.get('dependency_values'):
|
||||||
|
|||||||
Reference in New Issue
Block a user