Handle related fields in export_form_data (Z#23233538) (#6157)

This commit is contained in:
pajowu
2026-05-12 14:55:25 +02:00
committed by GitHub
parent b21b69b2b8
commit 82450c8250
6 changed files with 62 additions and 36 deletions

View File

@@ -133,37 +133,43 @@ class JobRunSerializer(serializers.Serializer):
return not bool(self._errors)
class ExportFormDataField(serializers.Field):
def get_attribute(self, instance):
return (instance.export_identifier, instance.export_form_data)
def to_representation(self, value):
export_identifier, export_form_data = value
exporter = self.context['exporters'].get(export_identifier)
if exporter:
return JobRunSerializer(exporter=exporter).to_representation(export_form_data)
else:
return export_form_data
def get_value(self, dictionary):
return dictionary
def to_internal_value(self, data):
if "export_form_data" in data:
identifier = data.get('export_identifier', self.parent.instance.export_identifier if self.parent.instance else None)
exporter = self.context['exporters'].get(identifier)
if exporter:
return JobRunSerializer(exporter=exporter).to_internal_value(data["export_form_data"])
else:
return data['export_form_data']
class ScheduledExportSerializer(serializers.ModelSerializer):
schedule_next_run = serializers.DateTimeField(read_only=True)
export_identifier = serializers.ChoiceField(choices=[])
locale = serializers.ChoiceField(choices=settings.LANGUAGES, default='en')
owner = serializers.SlugRelatedField(slug_field='email', read_only=True)
error_counter = serializers.IntegerField(read_only=True)
export_form_data = ExportFormDataField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['export_identifier'].choices = [(e, e) for e in self.context['exporters']]
def validate(self, attrs):
if attrs.get("export_form_data"):
identifier = attrs.get('export_identifier', self.instance.export_identifier if self.instance else None)
exporter = self.context['exporters'].get(identifier)
if exporter:
try:
attrs["export_form_data"] = JobRunSerializer(exporter=exporter).to_internal_value(attrs["export_form_data"])
except ValidationError as e:
raise ValidationError({"export_form_data": e.detail})
else:
raise ValidationError({"export_identifier": ["Unknown exporter."]})
return attrs
def to_representation(self, instance):
repr = super().to_representation(instance)
exporter = self.context['exporters'].get(instance.export_identifier)
if exporter:
repr["export_form_data"] = JobRunSerializer(exporter=exporter).to_representation(repr["export_form_data"])
return repr
def validate_mail_additional_recipients(self, value):
d = value.replace(' ', '')
if len(d.split(',')) > 25:

View File

@@ -45,6 +45,12 @@ class PrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
return value
return super().to_representation(value)
def to_internal_value(self, data):
value = super().to_internal_value(data)
if value is not None:
return value.pk
return value
class FormFieldWrapperField(serializers.Field):
def __init__(self, *args, **kwargs):

View File

@@ -82,7 +82,8 @@ class CheckInListMixin(BaseExporter):
widget=forms.RadioSelect(
attrs={'class': 'scrolling-choice'}
),
initial=self.event.checkin_lists.first()
initial=self.event.checkin_lists.first(),
required=True
)),
('date_range',
DateFrameField(
@@ -143,7 +144,6 @@ class CheckInListMixin(BaseExporter):
if not self.event.has_subevents:
del d['date_range']
d['list'].queryset = self.event.checkin_lists.all()
d['list'].widget = Select2(
attrs={
'data-model-select2': 'generic',
@@ -155,7 +155,6 @@ class CheckInListMixin(BaseExporter):
}
)
d['list'].widget.choices = d['list'].choices
d['list'].required = True
return d

View File

@@ -212,4 +212,17 @@ def membership_type(organizer):
return organizer.membership_types.create(name='foo')
@pytest.fixture
def clist(event, item):
c = event.checkin_lists.create(name="Default", all_products=False)
c.limit_products.add(item)
return c
@pytest.fixture
def clist_all(event, item):
c = event.checkin_lists.create(name="Default", all_products=True)
return c
utils.setup_databases = scopes_disabled()(utils.setup_databases)

View File

@@ -252,19 +252,6 @@ TEST_HISTORY_RES = {
}
@pytest.fixture
def clist(event, item):
c = event.checkin_lists.create(name="Default", all_products=False)
c.limit_products.add(item)
return c
@pytest.fixture
def clist_all(event, item):
c = event.checkin_lists.create(name="Default", all_products=True)
return c
@pytest.mark.django_db
def test_list_list(token_client, organizer, event, clist, item, subevent, django_assert_num_queries):
res = dict(TEST_LIST_RES)

View File

@@ -1079,3 +1079,18 @@ def test_event_edit_restrictions(client, event, organizer, user, team):
assert _get_and_patch_event_export(user2_client, s2)
assert _get_and_patch_event_export(team1_client, s2)
assert _get_and_patch_event_export(user1_client, s2)
@pytest.mark.django_db
def test_event_checkinlist_patch(user_client, organizer, event, user, event_scheduled_export, clist):
event_scheduled_export.export_identifier = "checkinlistpdf"
event_scheduled_export.save()
resp = user_client.patch(
'/api/v1/organizers/{}/events/{}/scheduled_exports/{}/'.format(organizer.slug, event.slug, event_scheduled_export.id),
data={
"export_form_data": {"list": clist.pk},
},
format='json',
)
assert resp.status_code == 200