diff --git a/src/pretix/base/shredder.py b/src/pretix/base/shredder.py index d7fd89093d..37463d5fc0 100644 --- a/src/pretix/base/shredder.py +++ b/src/pretix/base/shredder.py @@ -1,4 +1,5 @@ import json +import os from datetime import timedelta from typing import List, Tuple @@ -324,10 +325,16 @@ class QuestionAnswerShredder(BaseDataShredder): description = _('This will remove all answers to questions, as well as logged changes to them.') def generate_files(self) -> List[Tuple[str, str, str]]: - yield 'question-answers.json', 'application/json', json.dumps({ - '{}-{}'.format(op.order.code, op.positionid): AnswerSerializer(op.answers.all(), many=True).data - for op in OrderPosition.all.filter(order__event=self.event).prefetch_related('answers') - }, indent=4) + d = {} + for op in OrderPosition.all.filter(order__event=self.event).prefetch_related('answers', 'answers__question'): + for a in op.answers.all(): + if a.file: + fname = f'{op.order.code}-{op.positionid}-{a.question.identifier}-{os.path.basename(a.file.name)}' + yield fname, 'application/unknown', a.file.read() + d[f'{op.order.code}-{op.positionid}'] = AnswerSerializer( + sorted(op.answers.all(), key=lambda a: a.question_id), context={'request': None}, many=True + ).data + yield 'question-answers.json', 'application/json', json.dumps(d, indent=4) @transaction.atomic def shred_data(self): diff --git a/src/tests/base/test_shredders.py b/src/tests/base/test_shredders.py index bd9b86b973..e09f326451 100644 --- a/src/tests/base/test_shredders.py +++ b/src/tests/base/test_shredders.py @@ -226,6 +226,7 @@ def test_invoice_address_shredder(event, order): @pytest.mark.django_db def test_question_answer_shredder(event, order, question): opt = question.options.first() + q2 = event.questions.create(question="Photo", type="F", identifier="DEF") l1 = order.log_action( 'pretix.event.order.modified', data={ @@ -242,21 +243,33 @@ def test_question_answer_shredder(event, order, question): question=question, answer='S' ) + qa2 = QuestionAnswer.objects.create( + orderposition=order.positions.first(), + question=q2, + answer='file:///foo.pdf' + ) qa.file.save('foo.pdf', ContentFile('foo')) fname = qa.file.path assert os.path.exists(fname) qa.options.add(opt) s = QuestionAnswerShredder(event) f = list(s.generate_files()) - assert json.loads(f[0][2]) == { + assert json.loads(f[-1][2]) == { '{}-1'.format(order.code): [{ 'question': question.pk, 'answer': 'S', 'question_identifier': question.identifier, 'options': [opt.pk], 'option_identifiers': [opt.identifier], + }, { + 'question': q2.pk, + 'answer': f'/api/v1/organizers/dummy/events/dummy/orderpositions/{qa2.orderposition_id}/answer/{qa2.question_id}/', + 'question_identifier': q2.identifier, + 'options': [], + 'option_identifiers': [], }] } + assert f[0][0].endswith('.pdf') s.shred_data() order.refresh_from_db() assert not os.path.exists(fname)