QuestionnaireChild: system_question und user_question in system_datafield und user_datafield umbenennen

This commit is contained in:
Mira Weller
2026-08-13 16:40:20 +02:00
parent 50431047f1
commit e423c52540
12 changed files with 50 additions and 48 deletions
+1 -1
View File
@@ -975,7 +975,7 @@ class DeviceEventSettingsSerializer(EventSettingsSerializer):
'reusable_media_type_nfc_mf0aes',
'reusable_media_type_nfc_mf0aes_random_uid',
'reusable_media_usage_enforced',
'system_question_order',
'system_question_order', # TODO - remove or replace
'tax_rule_payment',
'tax_rule_cancellation',
]
+11 -11
View File
@@ -632,18 +632,18 @@ class QuestionRefField(serializers.PrimaryKeyRelatedField):
def to_representation(self, qc):
if not qc:
return None
elif qc.system_question:
return qc.system_question
elif qc.user_question_id:
return qc.user_question_id
elif qc.system_datafield:
return qc.system_datafield
elif qc.user_datafield_id:
return qc.user_datafield_id
else:
return None
def to_internal_value(self, data):
if type(data) == int:
return {'user_question': super().to_internal_value(data), 'system_question': None}
return {'user_datafield': super().to_internal_value(data), 'system_datafield': None}
elif type(data) == str or data is None:
return {'user_question': None, 'system_question': data}
return {'user_datafield': None, 'system_datafield': data}
else:
self.fail('incorrect_type', data_type=type(data).__name__)
@@ -737,13 +737,13 @@ class QuestionnaireSerializer(I18nAwareModelSerializer):
prev_questions = {}
for child in value:
if child.get('dependency_question'):
if (child['dependency_question']['user_question'] or child['dependency_question']['system_question']) not in prev_questions:
if (child['dependency_question']['user_datafield'] or child['dependency_question']['system_datafield']) not in prev_questions:
raise ValidationError('A question can only depend on a previous question from the same questionnaire.')
if child['user_question']:
prev_questions[child['user_question']] = child
if child['system_question']:
prev_questions[child['system_question']] = child
if child['user_datafield']:
prev_questions[child['user_datafield']] = child
if child['system_datafield']:
prev_questions[child['system_datafield']] = child
return value
@transaction.atomic
+5 -5
View File
@@ -980,11 +980,11 @@ class TicketLevelQuestionsForm(BaseQuestionsForm):
for questionnaire in questionnaires:
for child in getattr(questionnaire, 'childlist', questionnaire.children.all()):
if child.user_question:
df = child.user_question
if child.user_datafield:
df = child.user_datafield
self.fields['question_%s' % df.id] = self.build_user_question_field(request, event, pos.answerlist, child, df)
elif child.system_question:
self.fields[child.system_question] = self.build_system_question_field(request, event, pos, child)
elif child.system_datafield:
self.fields[child.system_datafield] = self.build_system_question_field(request, event, pos, child)
responses = question_form_fields.send(sender=event, position=pos)
data = pos.meta_info_data
@@ -1049,7 +1049,7 @@ class TicketLevelQuestionsForm(BaseQuestionsForm):
)
def build_system_question_field(self, request, event, pos, qc):
field_name = qc.system_question
field_name = qc.system_datafield
if field_name == 'attendee_name_parts':
return NamePartsFormField(
max_length=255,
@@ -72,7 +72,7 @@ def migrate_questions_forward(apps, schema_editor):
QuestionnaireChild.objects.create(
questionnaire=questionnaire,
position=position + 1,
system_question=child.id,
system_datafield=child.id,
required=child.required,
label=child.question,
)
@@ -80,7 +80,7 @@ def migrate_questions_forward(apps, schema_editor):
deps[child.id] = QuestionnaireChild.objects.create(
questionnaire=questionnaire,
position=position + 1,
user_question=child,
user_datafield=child,
required=child.required,
label=child.question,
help_text=child.help_text,
@@ -153,14 +153,14 @@ class Migration(migrations.Migration):
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
('position', models.PositiveIntegerField(default=0)),
('system_question', models.CharField(max_length=25, null=True)),
('system_datafield', models.CharField(max_length=25, null=True)),
('required', models.BooleanField(default=False)),
('label', i18nfield.fields.I18nTextField()),
('help_text', i18nfield.fields.I18nTextField(null=True)),
('dependency_values', pretix.base.models.fields.MultiStringField(default=[])),
('dependency_question', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dependent_questions', to='pretixbase.questionnairechild')),
('questionnaire', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='children', to='pretixbase.questionnaire')),
('user_question', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='references', to='pretixbase.question')),
('user_datafield', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='references', to='pretixbase.question')),
],
options={
'abstract': False,
+2 -2
View File
@@ -2045,13 +2045,13 @@ class QuestionnaireChild(LoggedModel):
default=0,
verbose_name=_("Position")
)
user_question = models.ForeignKey(
user_datafield = models.ForeignKey(
Question,
related_name="references",
on_delete=models.CASCADE,
null=True, blank=True,
)
system_question = models.CharField(
system_datafield = models.CharField(
max_length=25,
choices=SYSTEM_QUESTION_CHOICES,
null=True, blank=True,
+18 -18
View File
@@ -1656,11 +1656,11 @@ class AbstractPosition(RoundingCorrectionMixin, models.Model):
self.questions = []
for qc in children:
if qc.user_question_id and qc.user_question_id in self.answer_cache:
qc.answer = self.answer_cache[qc.user_question_id]
if qc.user_datafield_id and qc.user_datafield_id in self.answer_cache:
qc.answer = self.answer_cache[qc.user_datafield_id]
#qc.answer.question = qc # cache object
elif qc.system_question:
qc.answer = self.get_system_answer(qc.system_question)
elif qc.system_datafield:
qc.answer = self.get_system_answer(qc.system_datafield)
#qc.answer.question = qc # cache object
else:
qc.answer = ""
@@ -1674,30 +1674,30 @@ class AbstractPosition(RoundingCorrectionMixin, models.Model):
}
def get_dependency_answer_values(self, qc):
if qc.user_question_id:
if qc.user_question_id not in self.answer_cache:
if qc.user_datafield_id:
if qc.user_datafield_id not in self.answer_cache:
return None
answer = self.answer_cache[qc.user_question_id]
answer = self.answer_cache[qc.user_datafield_id]
return answer.to_dependency_values()
elif qc.system_question:
return [self.get_system_answer(qc.system_question)]
elif qc.system_datafield:
return [self.get_system_answer(qc.system_datafield)]
else:
raise ValueError('Questionnaire child without question has no answer')
raise ValueError('Questionnaire child without datafield has no answer')
def get_system_answer(self, system_question_name):
if system_question_name == 'attendee_name_parts':
def get_system_answer(self, system_datafield_name):
if system_datafield_name == 'attendee_name_parts':
return self.attendee_name_parts
elif system_question_name == 'attendee_email':
elif system_datafield_name == 'attendee_email':
return self.attendee_email
elif system_question_name == 'street':
elif system_datafield_name == 'street':
return self.street
elif system_question_name == 'zipcode':
elif system_datafield_name == 'zipcode':
return self.zipcode
elif system_question_name == 'city':
elif system_datafield_name == 'city':
return self.city
elif system_question_name == 'state':
elif system_datafield_name == 'state':
return self.state
elif system_question_name == 'country':
elif system_datafield_name == 'country':
return self.country
else:
raise ValueError('Unknown system question name')
+1 -1
View File
@@ -379,7 +379,7 @@ DEFAULTS = {
)
},
'system_question_order': {
'system_question_order': { # TODO - remove this
'default': {},
'type': dict,
'serializer_class': serializers.DictField,
+1 -1
View File
@@ -363,7 +363,7 @@ class OrderQuestionsViewMixin(BaseQuestionsViewMixin):
Prefetch('item__questionnaires',
qqs.prefetch_related(
Prefetch('children', QuestionnaireChild.objects.prefetch_related(
Prefetch('user_question', Question.objects.prefetch_related(
Prefetch('user_datafield', Question.objects.prefetch_related(
Prefetch('options', QuestionOption.objects.prefetch_related(Prefetch(
# This prefetch statement is utter bullshit, but it actually prevents Django from doing
# a lot of queries since ModelChoiceIterator stops trying to be clever once we have
@@ -20,8 +20,10 @@
{% endif %}
{% elif question.type == "M" %}
{{ answer.to_string_i18n|rich_text_snippet }}
{% elif question.type %}
{{ answer.to_string_i18n|rich_text_snippet }}
{% else %}
{{ answer.to_string_i18n|linebreaksbr }}
{{ answer|linebreaksbr }}
{% endif %}
{% else %}
<em>{% trans "not answered" %}</em>
@@ -651,7 +651,7 @@
{% endif %}
#}
{% include "pretixcontrol/order/fragment_question_answer.html" with request=request question=q answer=q.answer %}
{% if q.system_question == "attendee_email" and not line.addon_to %}
{% if q.system_datafield == "attendee_email" and not line.addon_to %}
<form class="form-inline helper-display-inline" method="post"
action="{% url "control:event.order.resendlink" event=request.event.slug organizer=request.event.organizer.slug code=order.code position=line.pk %}">
{% csrf_token %}
+2 -2
View File
@@ -1085,11 +1085,11 @@ class QuestionsStep(CartQuestionsViewMixin, CartMixin, TemplateFlowStep):
if not self.all_optional:
for qq in cp.item.relevant_questionnaires:
for qc in qq.childlist:
if qc.user_question_id and question_is_required(qc) and qc.user_question_id not in cp.answer_cache:
if qc.user_datafield_id and question_is_required(qc) and qc.user_datafield_id not in cp.answer_cache:
if warn:
messages.warning(request, _('Please fill in answers to all required questions.'))
return False
if qc.system_question and question_is_required(qc) and not cp.get_system_answer(qc.system_question):
if qc.system_datafield and question_is_required(qc) and not cp.get_system_answer(qc.system_datafield):
if warn:
messages.warning(request, _('Please fill in answers to all required questions.'))
return False
+1 -1
View File
@@ -436,7 +436,7 @@ def get_cart_positions(request):
Prefetch('item__questionnaires',
qqs.prefetch_related(
Prefetch('children', QuestionnaireChild.objects.prefetch_related(
Prefetch('user_question', Question.objects.prefetch_related(
Prefetch('user_datafield', Question.objects.prefetch_related(
Prefetch('options', QuestionOption.objects.prefetch_related(Prefetch(
# This prefetch statement is utter bullshit, but it actually prevents Django from doing
# a lot of queries since ModelChoiceIterator stops trying to be clever once we have