mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Export: Do not rely on cached answer option values (Z#23152831) (#4225)
* Export: Do not rely on cached answer option values * refactor duplicate code --------- Co-authored-by: Mira Weller <weller@rami.io>
This commit is contained in:
@@ -32,7 +32,7 @@
|
|||||||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations under the License.
|
# License for the specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict, defaultdict
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
@@ -605,10 +605,9 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
]
|
]
|
||||||
|
|
||||||
questions = list(Question.objects.filter(event__in=self.events))
|
questions = list(Question.objects.filter(event__in=self.events))
|
||||||
options = {}
|
options = defaultdict(list)
|
||||||
for q in questions:
|
for q in questions:
|
||||||
if q.type == Question.TYPE_CHOICE_MULTIPLE:
|
if q.type == Question.TYPE_CHOICE_MULTIPLE:
|
||||||
options[q.pk] = []
|
|
||||||
if form_data['group_multiple_choice']:
|
if form_data['group_multiple_choice']:
|
||||||
for o in q.options.all():
|
for o in q.options.all():
|
||||||
options[q.pk].append(o)
|
options[q.pk].append(o)
|
||||||
@@ -618,6 +617,9 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
headers.append(str(q.question) + ' – ' + str(o.answer))
|
headers.append(str(q.question) + ' – ' + str(o.answer))
|
||||||
options[q.pk].append(o)
|
options[q.pk].append(o)
|
||||||
else:
|
else:
|
||||||
|
if q.type == Question.TYPE_CHOICE:
|
||||||
|
for o in q.options.all():
|
||||||
|
options[q.pk].append(o)
|
||||||
headers.append(str(q.question))
|
headers.append(str(q.question))
|
||||||
headers += [
|
headers += [
|
||||||
_('Company'),
|
_('Company'),
|
||||||
@@ -727,7 +729,7 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
for a in op.answers.all():
|
for a in op.answers.all():
|
||||||
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
||||||
# to difficulties parsing the data (for example 2019-02-01 may become Février, 2019 01 in French).
|
# to difficulties parsing the data (for example 2019-02-01 may become Février, 2019 01 in French).
|
||||||
if a.question.type == Question.TYPE_CHOICE_MULTIPLE:
|
if a.question.type in (Question.TYPE_CHOICE_MULTIPLE, Question.TYPE_CHOICE):
|
||||||
acache[a.question_id] = set(o.pk for o in a.options.all())
|
acache[a.question_id] = set(o.pk for o in a.options.all())
|
||||||
elif a.question.type in Question.UNLOCALIZED_TYPES:
|
elif a.question.type in Question.UNLOCALIZED_TYPES:
|
||||||
acache[a.question_id] = a.answer
|
acache[a.question_id] = a.answer
|
||||||
@@ -740,6 +742,10 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
else:
|
else:
|
||||||
for o in options[q.pk]:
|
for o in options[q.pk]:
|
||||||
row.append(_('Yes') if o.pk in acache.get(q.pk, set()) else _('No'))
|
row.append(_('Yes') if o.pk in acache.get(q.pk, set()) else _('No'))
|
||||||
|
elif q.type == Question.TYPE_CHOICE:
|
||||||
|
# Join is only necessary if the question type was modified but also keeps the code simpler here
|
||||||
|
# as we'd otherwise need some [0] and existance checks
|
||||||
|
row.append(", ".join(str(o.answer) for o in options[q.pk] if o.pk in acache.get(q.pk, set())))
|
||||||
else:
|
else:
|
||||||
row.append(acache.get(q.pk, ''))
|
row.append(acache.get(q.pk, ''))
|
||||||
|
|
||||||
|
|||||||
@@ -281,6 +281,17 @@ class TableTextRotate(Flowable):
|
|||||||
canvas.drawString(0, -1, self.text)
|
canvas.drawString(0, -1, self.text)
|
||||||
|
|
||||||
|
|
||||||
|
def format_answer_for_export(a):
|
||||||
|
if a.question.type in (Question.TYPE_CHOICE, Question.TYPE_CHOICE_MULTIPLE):
|
||||||
|
return ", ".join(str(o.answer) for o in a.options.all())
|
||||||
|
elif a.question.type in Question.UNLOCALIZED_TYPES:
|
||||||
|
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
||||||
|
# to difficulties parsing the data (for example 2019-02-01 may become Février, 2019 01 in French).
|
||||||
|
return a.answer
|
||||||
|
else:
|
||||||
|
return str(a)
|
||||||
|
|
||||||
|
|
||||||
class PDFCheckinList(ReportlabExportMixin, CheckInListMixin, BaseExporter):
|
class PDFCheckinList(ReportlabExportMixin, CheckInListMixin, BaseExporter):
|
||||||
name = "overview"
|
name = "overview"
|
||||||
identifier = 'checkinlistpdf'
|
identifier = 'checkinlistpdf'
|
||||||
@@ -372,6 +383,14 @@ class PDFCheckinList(ReportlabExportMixin, CheckInListMixin, BaseExporter):
|
|||||||
tdata[0].append(p)
|
tdata[0].append(p)
|
||||||
|
|
||||||
qs = self._get_queryset(cl, form_data)
|
qs = self._get_queryset(cl, form_data)
|
||||||
|
qs = qs.prefetch_related(
|
||||||
|
'answers',
|
||||||
|
'answers__options',
|
||||||
|
'answers__question',
|
||||||
|
'addon_to__answers',
|
||||||
|
'addon_to__answers__question',
|
||||||
|
'addon_to__answers__options',
|
||||||
|
)
|
||||||
|
|
||||||
for op in qs:
|
for op in qs:
|
||||||
try:
|
try:
|
||||||
@@ -413,19 +432,9 @@ class PDFCheckinList(ReportlabExportMixin, CheckInListMixin, BaseExporter):
|
|||||||
acache = {}
|
acache = {}
|
||||||
if op.addon_to:
|
if op.addon_to:
|
||||||
for a in op.addon_to.answers.all():
|
for a in op.addon_to.answers.all():
|
||||||
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
acache[a.question_id] = format_answer_for_export(a)
|
||||||
# to difficulties parsing the data (for example 2019-02-01 may become Février, 2019 01 in French).
|
|
||||||
if a.question.type in Question.UNLOCALIZED_TYPES:
|
|
||||||
acache[a.question_id] = a.answer
|
|
||||||
else:
|
|
||||||
acache[a.question_id] = str(a)
|
|
||||||
for a in op.answers.all():
|
for a in op.answers.all():
|
||||||
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
acache[a.question_id] = format_answer_for_export(a)
|
||||||
# to difficulties parsing the data (for example 2019-02-01 may become Février, 2019 01 in French).
|
|
||||||
if a.question.type in Question.UNLOCALIZED_TYPES:
|
|
||||||
acache[a.question_id] = a.answer
|
|
||||||
else:
|
|
||||||
acache[a.question_id] = str(a)
|
|
||||||
for q in questions:
|
for q in questions:
|
||||||
txt = acache.get(q.pk, '')
|
txt = acache.get(q.pk, '')
|
||||||
txt = bleach.clean(txt, tags=['br']).strip().replace('<br>', '<br/>')
|
txt = bleach.clean(txt, tags=['br']).strip().replace('<br>', '<br/>')
|
||||||
@@ -525,7 +534,12 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
|
|||||||
yield headers
|
yield headers
|
||||||
|
|
||||||
qs = base_qs.prefetch_related(
|
qs = base_qs.prefetch_related(
|
||||||
'answers', 'answers__question', 'addon_to__answers', 'addon_to__answers__question'
|
'answers',
|
||||||
|
'answers__options',
|
||||||
|
'answers__question',
|
||||||
|
'addon_to__answers',
|
||||||
|
'addon_to__answers__question',
|
||||||
|
'addon_to__answers__options',
|
||||||
)
|
)
|
||||||
|
|
||||||
all_ids = list(base_qs.values_list('pk', flat=True))
|
all_ids = list(base_qs.values_list('pk', flat=True))
|
||||||
@@ -597,19 +611,9 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
|
|||||||
acache = {}
|
acache = {}
|
||||||
if op.addon_to:
|
if op.addon_to:
|
||||||
for a in op.addon_to.answers.all():
|
for a in op.addon_to.answers.all():
|
||||||
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
acache[a.question_id] = format_answer_for_export(a)
|
||||||
# to difficulties parsing the data (for example 2019-02-01 may become Février, 2019 01 in French).
|
|
||||||
if a.question.type in Question.UNLOCALIZED_TYPES:
|
|
||||||
acache[a.question_id] = a.answer
|
|
||||||
else:
|
|
||||||
acache[a.question_id] = str(a)
|
|
||||||
for a in op.answers.all():
|
for a in op.answers.all():
|
||||||
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
acache[a.question_id] = format_answer_for_export(a)
|
||||||
# to difficulties parsing the data (for example 2019-02-01 may become Février, 2019 01 in French).
|
|
||||||
if a.question.type in Question.UNLOCALIZED_TYPES:
|
|
||||||
acache[a.question_id] = a.answer
|
|
||||||
else:
|
|
||||||
acache[a.question_id] = str(a)
|
|
||||||
for q in questions:
|
for q in questions:
|
||||||
row.append(acache.get(q.pk, ''))
|
row.append(acache.get(q.pk, ''))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user