mirror of
https://github.com/pretix/pretix.git
synced 2026-09-14 16:24:43 +00:00
Add identifier field to questions
This commit is contained in:
@@ -129,7 +129,9 @@ downloads list of objects List of ticket
|
|||||||
answers list of objects Answers to user-defined questions
|
answers list of objects Answers to user-defined questions
|
||||||
├ question integer Internal ID of the answered question
|
├ question integer Internal ID of the answered question
|
||||||
├ answer string Text representation of the answer
|
├ answer string Text representation of the answer
|
||||||
└ options list of integers Internal IDs of selected option(s)s (only for choice types)
|
├ question_identifier string The question's ``identifier`` field
|
||||||
|
├ options list of integers Internal IDs of selected option(s)s (only for choice types)
|
||||||
|
└ option_identifiers list of strings The ``identifier`` fields of the selected option(s)s
|
||||||
===================================== ========================== =======================================================
|
===================================== ========================== =======================================================
|
||||||
|
|
||||||
.. versionchanged:: 1.7
|
.. versionchanged:: 1.7
|
||||||
@@ -140,6 +142,10 @@ answers list of objects Answers to user
|
|||||||
|
|
||||||
The attribute ``checkins.list`` has been added.
|
The attribute ``checkins.list`` has been added.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.14
|
||||||
|
|
||||||
|
The attributes ``answers.question_identifier`` and ``answers.option_identifiers`` have been added.
|
||||||
|
|
||||||
|
|
||||||
Order endpoints
|
Order endpoints
|
||||||
---------------
|
---------------
|
||||||
@@ -222,7 +228,9 @@ Order endpoints
|
|||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
|
"question_identifier": "WY3TP9SL",
|
||||||
"answer": "Foo",
|
"answer": "Foo",
|
||||||
|
"option_idenfiters": [],
|
||||||
"options": []
|
"options": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -330,7 +338,9 @@ Order endpoints
|
|||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
|
"question_identifier": "WY3TP9SL",
|
||||||
"answer": "Foo",
|
"answer": "Foo",
|
||||||
|
"option_idenfiters": [],
|
||||||
"options": []
|
"options": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -649,7 +659,9 @@ Order position endpoints
|
|||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
|
"question_identifier": "WY3TP9SL",
|
||||||
"answer": "Foo",
|
"answer": "Foo",
|
||||||
|
"option_idenfiters": [],
|
||||||
"options": []
|
"options": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -729,7 +741,9 @@ Order position endpoints
|
|||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
|
"question_identifier": "WY3TP9SL",
|
||||||
"answer": "Foo",
|
"answer": "Foo",
|
||||||
|
"option_idenfiters": [],
|
||||||
"options": []
|
"options": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -31,12 +31,16 @@ type string The expected ty
|
|||||||
required boolean If ``True``, the question needs to be filled out.
|
required boolean If ``True``, the question needs to be filled out.
|
||||||
position integer An integer, used for sorting
|
position integer An integer, used for sorting
|
||||||
items list of integers List of item IDs this question is assigned to.
|
items list of integers List of item IDs this question is assigned to.
|
||||||
|
identifier string An arbitrary string that can be used for matching with
|
||||||
|
other sources.
|
||||||
ask_during_checkin boolean If ``True``, this question will not be asked while
|
ask_during_checkin boolean If ``True``, this question will not be asked while
|
||||||
buying the ticket, but will show up when redeeming
|
buying the ticket, but will show up when redeeming
|
||||||
the ticket instead.
|
the ticket instead.
|
||||||
options list of objects In case of question type ``C`` or ``M``, this lists the
|
options list of objects In case of question type ``C`` or ``M``, this lists the
|
||||||
available objects.
|
available objects.
|
||||||
├ id integer Internal ID of the option
|
├ id integer Internal ID of the option
|
||||||
|
├ identifier string An arbitrary string that can be used for matching with
|
||||||
|
other sources.
|
||||||
└ answer multi-lingual string The displayed value of this option
|
└ answer multi-lingual string The displayed value of this option
|
||||||
===================================== ========================== =======================================================
|
===================================== ========================== =======================================================
|
||||||
|
|
||||||
@@ -45,6 +49,10 @@ options list of objects In case of ques
|
|||||||
The values ``D``, ``H``, and ``W`` for the field ``type`` are now allowed and the ``ask_during_checkin`` field has
|
The values ``D``, ``H``, and ``W`` for the field ``type`` are now allowed and the ``ask_during_checkin`` field has
|
||||||
been added.
|
been added.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.14
|
||||||
|
|
||||||
|
The attribute ``identifier`` has been added to both the resource itself and the ``options`` subresource.
|
||||||
|
|
||||||
Endpoints
|
Endpoints
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@@ -80,18 +88,22 @@ Endpoints
|
|||||||
"required": false,
|
"required": false,
|
||||||
"items": [1, 2],
|
"items": [1, 2],
|
||||||
"position": 1,
|
"position": 1,
|
||||||
|
"identifier": "WY3TP9SL",
|
||||||
"ask_during_checkin": false,
|
"ask_during_checkin": false,
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
|
"identifier": "LVETRWVU",
|
||||||
"answer": {"en": "S"}
|
"answer": {"en": "S"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
|
"identifier": "DFEMJWMJ",
|
||||||
"answer": {"en": "M"}
|
"answer": {"en": "M"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
|
"identifier": "W9AH7RDE",
|
||||||
"answer": {"en": "L"}
|
"answer": {"en": "L"}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -134,19 +146,23 @@ Endpoints
|
|||||||
"type": "C",
|
"type": "C",
|
||||||
"required": false,
|
"required": false,
|
||||||
"items": [1, 2],
|
"items": [1, 2],
|
||||||
"ask_during_checkin": false,
|
|
||||||
"position": 1,
|
"position": 1,
|
||||||
|
"identifier": "WY3TP9SL",
|
||||||
|
"ask_during_checkin": false,
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
|
"identifier": "LVETRWVU",
|
||||||
"answer": {"en": "S"}
|
"answer": {"en": "S"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
|
"identifier": "DFEMJWMJ",
|
||||||
"answer": {"en": "M"}
|
"answer": {"en": "M"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
|
"identifier": "W9AH7RDE",
|
||||||
"answer": {"en": "L"}
|
"answer": {"en": "L"}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class InlineQuestionOptionSerializer(I18nAwareModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = QuestionOption
|
model = QuestionOption
|
||||||
fields = ('id', 'answer')
|
fields = ('id', 'identifier', 'answer')
|
||||||
|
|
||||||
|
|
||||||
class QuestionSerializer(I18nAwareModelSerializer):
|
class QuestionSerializer(I18nAwareModelSerializer):
|
||||||
@@ -151,7 +151,7 @@ class QuestionSerializer(I18nAwareModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Question
|
model = Question
|
||||||
fields = ('id', 'question', 'type', 'required', 'items', 'options', 'position',
|
fields = ('id', 'question', 'type', 'required', 'items', 'options', 'position',
|
||||||
'ask_during_checkin')
|
'ask_during_checkin', 'identifier')
|
||||||
|
|
||||||
|
|
||||||
class QuotaSerializer(I18nAwareModelSerializer):
|
class QuotaSerializer(I18nAwareModelSerializer):
|
||||||
|
|||||||
@@ -29,10 +29,23 @@ class InvoiceAdddressSerializer(I18nAwareModelSerializer):
|
|||||||
'vat_id_validated', 'internal_reference')
|
'vat_id_validated', 'internal_reference')
|
||||||
|
|
||||||
|
|
||||||
|
class AnswerQuestionIdentifierField(serializers.Field):
|
||||||
|
def to_representation(self, instance: QuestionAnswer):
|
||||||
|
return instance.question.identifier
|
||||||
|
|
||||||
|
|
||||||
|
class AnswerQuestionOptionsIdentifierField(serializers.Field):
|
||||||
|
def to_representation(self, instance: QuestionAnswer):
|
||||||
|
return [o.identifier for o in instance.options.all()]
|
||||||
|
|
||||||
|
|
||||||
class AnswerSerializer(I18nAwareModelSerializer):
|
class AnswerSerializer(I18nAwareModelSerializer):
|
||||||
|
question_identifier = AnswerQuestionIdentifierField(source='*', read_only=True)
|
||||||
|
option_identifiers = AnswerQuestionOptionsIdentifierField(source='*', read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = QuestionAnswer
|
model = QuestionAnswer
|
||||||
fields = ('question', 'answer', 'options')
|
fields = ('question', 'answer', 'question_identifier', 'options', 'option_identifiers')
|
||||||
|
|
||||||
|
|
||||||
class CheckinSerializer(I18nAwareModelSerializer):
|
class CheckinSerializer(I18nAwareModelSerializer):
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class OrderViewSet(viewsets.ReadOnlyModelViewSet):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.request.event.orders.prefetch_related(
|
return self.request.event.orders.prefetch_related(
|
||||||
'positions', 'positions__checkins', 'positions__item', 'positions__answers', 'positions__answers__options',
|
'positions', 'positions__checkins', 'positions__item', 'positions__answers', 'positions__answers__options',
|
||||||
'fees'
|
'positions__answers__questions', 'fees'
|
||||||
).select_related(
|
).select_related(
|
||||||
'invoice_address'
|
'invoice_address'
|
||||||
)
|
)
|
||||||
@@ -234,7 +234,7 @@ class OrderPositionViewSet(viewsets.ReadOnlyModelViewSet):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return OrderPosition.objects.filter(order__event=self.request.event).prefetch_related(
|
return OrderPosition.objects.filter(order__event=self.request.event).prefetch_related(
|
||||||
'checkins', 'answers', 'answers__options'
|
'checkins', 'answers', 'answers__options', 'answers__question'
|
||||||
).select_related(
|
).select_related(
|
||||||
'item', 'order', 'order__event', 'order__event__organizer'
|
'item', 'order', 'order__event', 'order__event__organizer'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.11 on 2018-03-12 11:19
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
from django.utils.crypto import get_random_string
|
||||||
|
|
||||||
|
|
||||||
|
def set_identifiers(apps, schema_editor):
|
||||||
|
Question = apps.get_model('pretixbase', 'Question')
|
||||||
|
QuestionOption = apps.get_model('pretixbase', 'QuestionOption')
|
||||||
|
|
||||||
|
for q in Question.objects.select_related('event'):
|
||||||
|
if not q.identifier:
|
||||||
|
charset = list('ABCDEFGHJKLMNPQRSTUVWXYZ3789')
|
||||||
|
while True:
|
||||||
|
code = get_random_string(length=8, allowed_chars=charset)
|
||||||
|
if not Question.objects.filter(event=q.event, identifier=code).exists():
|
||||||
|
q.identifier = code
|
||||||
|
q.save()
|
||||||
|
break
|
||||||
|
|
||||||
|
for q in QuestionOption.objects.select_related('question', 'question__event'):
|
||||||
|
if not q.identifier:
|
||||||
|
charset = list('ABCDEFGHJKLMNPQRSTUVWXYZ3789')
|
||||||
|
while True:
|
||||||
|
code = get_random_string(length=8, allowed_chars=charset)
|
||||||
|
if not QuestionOption.objects.filter(question__event=q.question.event, identifier=code).exists():
|
||||||
|
q.identifier = code
|
||||||
|
q.save()
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pretixbase', '0084_questionoption_position'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='question',
|
||||||
|
name='identifier',
|
||||||
|
field=models.CharField(default='', max_length=190),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='questionoption',
|
||||||
|
name='identifier',
|
||||||
|
field=models.CharField(default='', max_length=190),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='user',
|
||||||
|
name='locale',
|
||||||
|
field=models.CharField(choices=[('en', 'English'), ('de', 'German'), ('de-informal', 'German (informal)'), ('nl', 'Dutch'), ('da', 'Danish'), ('pt-br', 'Portuguese (Brazil)')], default='en', max_length=50, verbose_name='Language'),
|
||||||
|
),
|
||||||
|
migrations.RunPython(set_identifiers, migrations.RunPython.noop)
|
||||||
|
]
|
||||||
@@ -11,6 +11,7 @@ from django.core.exceptions import ValidationError
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import F, Func, Q, Sum
|
from django.db.models import F, Func, Q, Sum
|
||||||
from django.utils import formats
|
from django.utils import formats
|
||||||
|
from django.utils.crypto import get_random_string
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.timezone import is_naive, make_aware, now
|
from django.utils.timezone import is_naive, make_aware, now
|
||||||
from django.utils.translation import pgettext_lazy, ugettext_lazy as _
|
from django.utils.translation import pgettext_lazy, ugettext_lazy as _
|
||||||
@@ -630,6 +631,8 @@ class Question(LoggedModel):
|
|||||||
:param items: A set of ``Items`` objects that this question should be applied to
|
:param items: A set of ``Items`` objects that this question should be applied to
|
||||||
:param ask_during_checkin: Whether to ask this question during check-in instead of during check-out.
|
:param ask_during_checkin: Whether to ask this question during check-in instead of during check-out.
|
||||||
:type ask_during_checkin: bool
|
:type ask_during_checkin: bool
|
||||||
|
:param identifier: An arbitrary, internal identifier
|
||||||
|
:type identifier: str
|
||||||
"""
|
"""
|
||||||
TYPE_NUMBER = "N"
|
TYPE_NUMBER = "N"
|
||||||
TYPE_STRING = "S"
|
TYPE_STRING = "S"
|
||||||
@@ -661,6 +664,12 @@ class Question(LoggedModel):
|
|||||||
question = I18nTextField(
|
question = I18nTextField(
|
||||||
verbose_name=_("Question")
|
verbose_name=_("Question")
|
||||||
)
|
)
|
||||||
|
identifier = models.CharField(
|
||||||
|
max_length=190,
|
||||||
|
verbose_name=_("Internal identifier"),
|
||||||
|
help_text=_('You can enter any value here to make it easier to match the data with other sources. If you do '
|
||||||
|
'not input one, we will generate one automatically.')
|
||||||
|
)
|
||||||
help_text = I18nTextField(
|
help_text = I18nTextField(
|
||||||
verbose_name=_("Help text"),
|
verbose_name=_("Help text"),
|
||||||
help_text=_("If the question needs to be explained or clarified, do it here!"),
|
help_text=_("If the question needs to be explained or clarified, do it here!"),
|
||||||
@@ -706,7 +715,18 @@ class Question(LoggedModel):
|
|||||||
if self.event:
|
if self.event:
|
||||||
self.event.cache.clear()
|
self.event.cache.clear()
|
||||||
|
|
||||||
|
def clean_identifier(self, code):
|
||||||
|
if Question.objects.filter(event=self.event, identifier=code).exclude(pk=self.pk).exists():
|
||||||
|
raise ValidationError(_('This identifier is already used for a different question.'))
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.identifier:
|
||||||
|
charset = list('ABCDEFGHJKLMNPQRSTUVWXYZ3789')
|
||||||
|
while True:
|
||||||
|
code = get_random_string(length=8, allowed_chars=charset)
|
||||||
|
if not Question.objects.filter(event=self.event, identifier=code).exists():
|
||||||
|
self.identifier = code
|
||||||
|
break
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
if self.event:
|
if self.event:
|
||||||
self.event.cache.clear()
|
self.event.cache.clear()
|
||||||
@@ -779,12 +799,23 @@ class Question(LoggedModel):
|
|||||||
|
|
||||||
class QuestionOption(models.Model):
|
class QuestionOption(models.Model):
|
||||||
question = models.ForeignKey('Question', related_name='options')
|
question = models.ForeignKey('Question', related_name='options')
|
||||||
|
identifier = models.CharField(max_length=190)
|
||||||
answer = I18nCharField(verbose_name=_('Answer'))
|
answer = I18nCharField(verbose_name=_('Answer'))
|
||||||
position = models.IntegerField(default=0)
|
position = models.IntegerField(default=0)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.answer)
|
return str(self.answer)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.identifier:
|
||||||
|
charset = list('ABCDEFGHJKLMNPQRSTUVWXYZ3789')
|
||||||
|
while True:
|
||||||
|
code = get_random_string(length=8, allowed_chars=charset)
|
||||||
|
if not QuestionOption.objects.filter(question__event=self.question.event, identifier=code).exists():
|
||||||
|
self.identifier = code
|
||||||
|
break
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Question option")
|
verbose_name = _("Question option")
|
||||||
verbose_name_plural = _("Question options")
|
verbose_name_plural = _("Question options")
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class QuestionForm(I18nModelForm):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['items'].queryset = self.instance.event.items.all()
|
self.fields['items'].queryset = self.instance.event.items.all()
|
||||||
|
self.fields['identifier'].required = False
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Question
|
model = Question
|
||||||
@@ -51,6 +52,7 @@ class QuestionForm(I18nModelForm):
|
|||||||
'type',
|
'type',
|
||||||
'required',
|
'required',
|
||||||
'ask_during_checkin',
|
'ask_during_checkin',
|
||||||
|
'identifier',
|
||||||
'items'
|
'items'
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
{% bootstrap_field form.question layout="control" %}
|
{% bootstrap_field form.question layout="control" %}
|
||||||
{% bootstrap_field form.help_text layout="control" %}
|
{% bootstrap_field form.help_text layout="control" %}
|
||||||
{% bootstrap_field form.type layout="control" %}
|
{% bootstrap_field form.type layout="control" %}
|
||||||
|
{% bootstrap_field form.identifier layout="control" %}
|
||||||
{% bootstrap_field form.ask_during_checkin layout="control" %}
|
{% bootstrap_field form.ask_during_checkin layout="control" %}
|
||||||
{% bootstrap_field form.required layout="control" %}
|
{% bootstrap_field form.required layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -54,10 +55,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row question-option-row">
|
<div class="row question-option-row">
|
||||||
<div class="col-xs-10">
|
<div class="col-xs-10">
|
||||||
|
<span class="text-muted">
|
||||||
|
{% blocktrans trimmed with id=form.instance.identifier %}
|
||||||
|
Answer option {{ id }}
|
||||||
|
{% endblocktrans %}
|
||||||
|
</span>
|
||||||
{% bootstrap_form_errors form %}
|
{% bootstrap_form_errors form %}
|
||||||
{% bootstrap_field form.answer layout='inline' form_group_class="" %}
|
{% bootstrap_field form.answer layout='inline' form_group_class="" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-2 text-right">
|
<div class="col-xs-2 text-right">
|
||||||
|
<span> </span><br>
|
||||||
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
||||||
<i class="fa fa-arrow-up"></i></button>
|
<i class="fa fa-arrow-up"></i></button>
|
||||||
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
||||||
@@ -79,9 +86,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row question-option-row">
|
<div class="row question-option-row">
|
||||||
<div class="col-xs-10">
|
<div class="col-xs-10">
|
||||||
|
<span class="text-muted">
|
||||||
|
{% trans "New answer option" %}
|
||||||
|
</span>
|
||||||
{% bootstrap_field formset.empty_form.answer layout='inline' form_group_class="" %}
|
{% bootstrap_field formset.empty_form.answer layout='inline' form_group_class="" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-2 text-right">
|
<div class="col-xs-2 text-right">
|
||||||
|
<span> </span><br>
|
||||||
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
||||||
<i class="fa fa-arrow-up"></i></button>
|
<i class="fa fa-arrow-up"></i></button>
|
||||||
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
||||||
|
|||||||
@@ -1187,9 +1187,9 @@ def test_quota_availability(token_client, organizer, event, quota, item):
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def question(event, item):
|
def question(event, item):
|
||||||
q = event.questions.create(question="T-Shirt size", type="C")
|
q = event.questions.create(question="T-Shirt size", type="C", identifier="ABC")
|
||||||
q.items.add(item)
|
q.items.add(item)
|
||||||
q.options.create(answer="XL")
|
q.options.create(answer="XL", identifier="FOO")
|
||||||
return q
|
return q
|
||||||
|
|
||||||
|
|
||||||
@@ -1199,10 +1199,12 @@ TEST_QUESTION_RES = {
|
|||||||
"required": False,
|
"required": False,
|
||||||
"items": [],
|
"items": [],
|
||||||
"ask_during_checkin": False,
|
"ask_during_checkin": False,
|
||||||
|
"identifier": "ABC",
|
||||||
"position": 0,
|
"position": 0,
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
|
"identifier": "FOO",
|
||||||
"answer": {"en": "XL"}
|
"answer": {"en": "XL"}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user