mirror of
https://github.com/pretix/pretix.git
synced 2026-10-01 19:14:43 +00:00
MixedAnswerListSerializer - wip
This commit is contained in:
@@ -31,7 +31,7 @@ from rest_framework.exceptions import ValidationError
|
||||
|
||||
from pretix.api.serializers.i18n import I18nAwareModelSerializer
|
||||
from pretix.api.serializers.order import (
|
||||
AnswerCreateSerializer, AnswerSerializer, InlineSeatSerializer,
|
||||
AnswerCreateSerializer, AnswerSerializer, InlineSeatSerializer, MixedAnswerListSerializer,
|
||||
)
|
||||
from pretix.base.models import SalesChannel, Seat, Voucher
|
||||
from pretix.base.models.orders import CartPosition
|
||||
@@ -43,7 +43,7 @@ class TaxIncludedField(serializers.Field):
|
||||
|
||||
|
||||
class CartPositionSerializer(I18nAwareModelSerializer):
|
||||
answers = AnswerSerializer(many=True)
|
||||
answers = MixedAnswerListSerializer(child=AnswerSerializer(), source='*')
|
||||
seat = InlineSeatSerializer()
|
||||
includes_tax = TaxIncludedField(source='*')
|
||||
|
||||
@@ -55,7 +55,7 @@ class CartPositionSerializer(I18nAwareModelSerializer):
|
||||
|
||||
|
||||
class BaseCartPositionCreateSerializer(I18nAwareModelSerializer):
|
||||
answers = AnswerCreateSerializer(many=True, required=False)
|
||||
answers = MixedAnswerListSerializer(child=AnswerCreateSerializer(required=False), source='*', required=False)
|
||||
attendee_name = serializers.CharField(required=False, allow_null=True)
|
||||
includes_tax = serializers.BooleanField(required=False, allow_null=True)
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.relations import SlugRelatedField
|
||||
from rest_framework.reverse import reverse
|
||||
from rest_framework.serializers import ListSerializer
|
||||
|
||||
from pretix.api.auth.utils import get_session_key_for_api_request
|
||||
from pretix.api.serializers import CompatDecimalField, CompatibleJSONField
|
||||
@@ -47,7 +48,7 @@ from pretix.api.serializers.event import SubEventSerializer
|
||||
from pretix.api.serializers.forms import form_field_to_serializer_field
|
||||
from pretix.api.serializers.i18n import I18nAwareModelSerializer
|
||||
from pretix.api.serializers.item import (
|
||||
InlineItemVariationSerializer, ItemSerializer, DatafieldSerializer,
|
||||
InlineItemVariationSerializer, ItemSerializer, DatafieldSerializer, cook_id, system_datafield_numbers, uncook_id,
|
||||
)
|
||||
from pretix.api.signals import order_api_details, orderposition_api_details
|
||||
from pretix.base.decimal import round_decimal
|
||||
@@ -57,7 +58,7 @@ from pretix.base.media import MEDIA_TYPES
|
||||
from pretix.base.models import (
|
||||
CachedFile, Checkin, Customer, Device, GiftCard, Invoice, InvoiceAddress,
|
||||
InvoiceLine, Item, ItemVariation, Order, OrderPosition, Question,
|
||||
QuestionAnswer, ReusableMedium, SalesChannel, Seat, SubEvent, TaxRule,
|
||||
QuestionAnswer, QuestionnaireChild, ReusableMedium, SalesChannel, Seat, SubEvent, TaxRule,
|
||||
Voucher,
|
||||
)
|
||||
from pretix.base.models.orders import (
|
||||
@@ -229,6 +230,50 @@ class InlineSeatSerializer(I18nAwareModelSerializer):
|
||||
fields = ('id', 'name', 'seat_guid', 'zone_name', 'row_name', 'row_label', 'seat_label', 'seat_number')
|
||||
|
||||
|
||||
class MixedAnswerListSerializer(ListSerializer):
|
||||
def __init__(self, instance=None, *args, **kwargs):
|
||||
self.parent_instance = instance
|
||||
super().__init__(instance.answers if instance else None, *args, **kwargs)
|
||||
|
||||
def get_value(self, dictionary):
|
||||
return dictionary
|
||||
|
||||
def to_representation(self, instance):
|
||||
answers = super().to_representation(instance.answers)
|
||||
for qc in QuestionnaireChild.objects.filter(questionnaire__items__id=instance.item_id, system_datafield__isnull=False):
|
||||
answers.append({
|
||||
"question": cook_id(qc),
|
||||
"answer": instance.get_system_answer(qc.system_datafield),
|
||||
"question_identifier": f'@{qc.system_datafield}',
|
||||
"options": [],
|
||||
"option_identifiers": [],
|
||||
"questionnaire_id": qc.questionnaire_id,
|
||||
"system_datafield": qc.system_datafield,
|
||||
})
|
||||
return {
|
||||
"answers": answers,
|
||||
}
|
||||
|
||||
def to_internal_value(self, data):
|
||||
result = {}
|
||||
answers = []
|
||||
for answer in data["answers"]:
|
||||
try:
|
||||
qid, dfid, sys_df = uncook_id(answer["question"])
|
||||
except ValueError:
|
||||
if type(answer["question"]) is str and answer["question"].lstrip("@") in system_datafield_numbers:
|
||||
qid, dfid, sys_df = None, None, answer["question"].lstrip("@")
|
||||
else:
|
||||
raise
|
||||
if dfid:
|
||||
answer["question"] = dfid
|
||||
answers.append(answer)
|
||||
else:
|
||||
result[sys_df] = Country(answer["answer"]) if sys_df == "country" else answer["answer"]
|
||||
result["answers"] = super().to_internal_value(answers)
|
||||
return result
|
||||
|
||||
|
||||
class AnswerSerializer(I18nAwareModelSerializer):
|
||||
question_identifier = AnswerQuestionIdentifierField(source='*', read_only=True)
|
||||
option_identifiers = AnswerQuestionOptionsIdentifierField(source='*', read_only=True)
|
||||
@@ -591,7 +636,7 @@ class OrderPositionPluginDataField(serializers.Field):
|
||||
class OrderPositionSerializer(I18nAwareModelSerializer):
|
||||
checkins = InlineCheckinSerializer(many=True, read_only=True)
|
||||
print_logs = PrintLogSerializer(many=True, read_only=True)
|
||||
answers = AnswerSerializer(many=True)
|
||||
answers = MixedAnswerListSerializer(child=AnswerSerializer(), source='*')
|
||||
downloads = PositionDownloadsField(source='*', read_only=True)
|
||||
order = serializers.SlugRelatedField(slug_field='code', read_only=True)
|
||||
pdf_data = PdfDataSerializer(source='*', read_only=True)
|
||||
@@ -1041,7 +1086,7 @@ class OrderFeeCreateSerializer(I18nAwareModelSerializer):
|
||||
|
||||
|
||||
class OrderPositionCreateSerializer(I18nAwareModelSerializer):
|
||||
answers = AnswerCreateSerializer(many=True, required=False)
|
||||
answers = MixedAnswerListSerializer(child=AnswerCreateSerializer(required=False), source='*', required=False)
|
||||
addon_to = serializers.IntegerField(required=False, allow_null=True)
|
||||
secret = serializers.CharField(required=False)
|
||||
attendee_name = serializers.CharField(required=False, allow_null=True)
|
||||
|
||||
@@ -30,7 +30,7 @@ from rest_framework.exceptions import ValidationError
|
||||
|
||||
from pretix.api.serializers.order import (
|
||||
AnswerCreateSerializer, AnswerSerializer, CompatibleCountryField,
|
||||
OrderFeeCreateSerializer, OrderPositionCreateSerializer,
|
||||
MixedAnswerListSerializer, OrderFeeCreateSerializer, OrderPositionCreateSerializer,
|
||||
)
|
||||
from pretix.base.models import ItemVariation, Order, OrderFee, OrderPosition
|
||||
from pretix.base.services.orders import OrderChangeManager, OrderError
|
||||
@@ -41,7 +41,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class OrderPositionCreateForExistingOrderSerializer(OrderPositionCreateSerializer):
|
||||
order = serializers.SlugRelatedField(slug_field='code', queryset=Order.objects.none(), required=True, allow_null=False)
|
||||
answers = AnswerCreateSerializer(many=True, required=False)
|
||||
answers = MixedAnswerListSerializer(child=AnswerCreateSerializer(required=False), source='*', required=False)
|
||||
addon_to = serializers.IntegerField(required=False, allow_null=True)
|
||||
secret = serializers.CharField(required=False)
|
||||
attendee_name = serializers.CharField(required=False, allow_null=True)
|
||||
@@ -154,7 +154,7 @@ class OrderFeeCreateForExistingOrderSerializer(OrderFeeCreateSerializer):
|
||||
|
||||
|
||||
class OrderPositionInfoPatchSerializer(serializers.ModelSerializer):
|
||||
answers = AnswerSerializer(many=True)
|
||||
answers = MixedAnswerListSerializer(child=AnswerSerializer(), source='*')
|
||||
country = CompatibleCountryField(source='*')
|
||||
attendee_name = serializers.CharField(required=False)
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ class OrderViewSetMixin:
|
||||
[request.event],
|
||||
Prefetch('meta_values', queryset=EventMetaValue.objects.select_related('property'),
|
||||
to_attr='meta_values_cached'),
|
||||
'questions',
|
||||
'questionnaires',
|
||||
'item_meta_properties',
|
||||
)
|
||||
return Prefetch(
|
||||
@@ -287,7 +287,9 @@ class OrderViewSetMixin:
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||
'item', 'variation',
|
||||
Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options', 'question').order_by('question__position')),
|
||||
Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options', 'question')
|
||||
# TODO(questionnaires) .order_by('question__position')
|
||||
),
|
||||
'seat',
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user