API: Allow to whiteliste fields for the orders resource

This commit is contained in:
Raphael Michel
2022-11-28 10:57:12 +01:00
parent 0a30fa70da
commit b72dc0ce8e
4 changed files with 81 additions and 0 deletions

View File

@@ -622,6 +622,23 @@ class OrderSerializer(I18nAwareModelSerializer):
if not self.context['pdf_data']:
self.fields['positions'].child.fields.pop('pdf_data', None)
includes = set(self.context['include'])
if includes:
for fname, field in list(self.fields.items()):
if fname in includes:
continue
elif hasattr(field, 'child'):
found_any = False
for childfname, childfield in list(field.child.fields.items()):
if f'{fname}.{childfname}' not in includes:
field.child.fields.pop(childfname)
else:
found_any = True
if not found_any:
self.fields.pop(fname)
else:
self.fields.pop(fname)
for exclude_field in self.context['exclude']:
p = exclude_field.split('.')
if p[0] in self.fields:

View File

@@ -191,6 +191,7 @@ class OrderViewSet(viewsets.ModelViewSet):
ctx['event'] = self.request.event
ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false') == 'true'
ctx['exclude'] = self.request.query_params.getlist('exclude')
ctx['include'] = self.request.query_params.getlist('include')
return ctx
def get_queryset(self):

View File

@@ -442,6 +442,64 @@ def test_order_detail(token_client, organizer, event, order, item, taxrule, ques
assert len(resp.data['fees']) == 2
@pytest.mark.django_db
def test_include_exclude_fields(token_client, organizer, event, order, item, taxrule, question):
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/{}/?exclude=positions.secret'.format(
organizer.slug, event.slug, order.code
))
assert resp.status_code == 200
assert 'email' in resp.data
assert 'url' in resp.data
assert 'positions' in resp.data
assert 'subevent' in resp.data['positions'][0]
assert 'secret' not in resp.data['positions'][0]
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/{}/?exclude=positions'.format(
organizer.slug, event.slug, order.code
))
assert resp.status_code == 200
assert 'email' in resp.data
assert 'url' in resp.data
assert 'positions' not in resp.data
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/{}/?exclude=email&exclude=url'.format(
organizer.slug, event.slug, order.code
))
assert resp.status_code == 200
assert 'email' not in resp.data
assert 'url' not in resp.data
assert 'positions' in resp.data
assert 'secret' in resp.data['positions'][0]
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/{}/?include=email'.format(
organizer.slug, event.slug, order.code
))
assert resp.status_code == 200
assert 'email' in resp.data
assert 'url' not in resp.data
assert 'positions' not in resp.data
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/{}/?include=email&include=positions&exclude=positions.secret'.format(
organizer.slug, event.slug, order.code
))
assert resp.status_code == 200
assert 'email' in resp.data
assert 'url' not in resp.data
assert 'positions' in resp.data
assert 'subevent' in resp.data['positions'][0]
assert 'secret' not in resp.data['positions'][0]
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/{}/?include=email&include=positions.subevent'.format(
organizer.slug, event.slug, order.code
))
assert resp.status_code == 200
assert 'email' in resp.data
assert 'url' not in resp.data
assert 'positions' in resp.data
assert 'subevent' in resp.data['positions'][0]
assert 'secret' not in resp.data['positions'][0]
@pytest.mark.django_db
def test_payment_list(token_client, organizer, event, order):
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/{}/payments/'.format(organizer.slug, event.slug,