API: Add timezone attribute to events

Note: I still believe the issues described in https://github.com/pretix/pretix/issues/1378
are a problem, and I'm still not keen on adding settings properties to
the API until we have a proper design for it. However, I'm making an
exception here since the list of events can't be used in a very useful
way with not access to the timezone.
This commit is contained in:
Raphael Michel
2020-01-11 13:24:19 +01:00
parent c1d6d9bf1a
commit 402730df43
4 changed files with 44 additions and 4 deletions

View File

@@ -42,6 +42,7 @@ seating_plan integer If reserved sea
plan. Otherwise ``null``.
seat_category_mapping object An object mapping categories of the seating plan
(strings) to items in the event (integers or ``null``).
timezone string Event timezone name
===================================== ========================== =======================================================
@@ -74,6 +75,10 @@ seat_category_mapping object An object mappi
The attributes ``geo_lat`` and ``geo_lon`` have been added.
.. versionchanged:: 3.4
The attribute ``timezone`` has been added.
Endpoints
---------
@@ -127,6 +132,7 @@ Endpoints
"meta_data": {},
"seating_plan": null,
"seat_category_mapping": {},
"timezone": "Europe/Berlin",
"plugins": [
"pretix.plugins.banktransfer"
"pretix.plugins.stripe"
@@ -197,6 +203,7 @@ Endpoints
"seating_plan": null,
"seat_category_mapping": {},
"meta_data": {},
"timezone": "Europe/Berlin",
"plugins": [
"pretix.plugins.banktransfer"
"pretix.plugins.stripe"
@@ -248,6 +255,7 @@ Endpoints
"geo_lon": null,
"has_subevents": false,
"meta_data": {},
"timezone": "Europe/Berlin",
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal"
@@ -281,6 +289,7 @@ Endpoints
"seat_category_mapping": {},
"has_subevents": false,
"meta_data": {},
"timezone": "Europe/Berlin",
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal"
@@ -334,6 +343,7 @@ Endpoints
"seat_category_mapping": {},
"has_subevents": false,
"meta_data": {},
"timezone": "Europe/Berlin",
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal"
@@ -367,6 +377,7 @@ Endpoints
"seating_plan": null,
"seat_category_mapping": {},
"meta_data": {},
"timezone": "Europe/Berlin",
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal"
@@ -432,6 +443,7 @@ Endpoints
"seating_plan": null,
"seat_category_mapping": {},
"meta_data": {},
"timezone": "Europe/Berlin",
"plugins": [
"pretix.plugins.banktransfer",
"pretix.plugins.stripe",

View File

@@ -4,7 +4,8 @@ from django.db import transaction
from django.utils.functional import cached_property
from django.utils.translation import ugettext as _
from django_countries.serializers import CountryFieldMixin
from rest_framework.fields import Field
from pytz import common_timezones
from rest_framework.fields import ChoiceField, Field
from rest_framework.relations import SlugRelatedField
from pretix.api.serializers.i18n import I18nAwareModelSerializer
@@ -61,17 +62,27 @@ class PluginsField(Field):
}
class TimeZoneField(ChoiceField):
def get_attribute(self, instance):
return instance.cache.get_or_set(
'timezone_name',
lambda: instance.settings.timezone,
3600
)
class EventSerializer(I18nAwareModelSerializer):
meta_data = MetaDataField(required=False, source='*')
plugins = PluginsField(required=False, source='*')
seat_category_mapping = SeatCategoryMappingField(source='*', required=False)
timezone = TimeZoneField(required=False, choices=[(a, a) for a in common_timezones])
class Meta:
model = Event
fields = ('name', 'slug', 'live', 'testmode', 'currency', 'date_from',
'date_to', 'date_admission', 'is_public', 'presale_start',
'presale_end', 'location', 'geo_lat', 'geo_lon', 'has_subevents', 'meta_data', 'seating_plan',
'plugins', 'seat_category_mapping')
'plugins', 'seat_category_mapping', 'timezone')
def validate(self, data):
data = super().validate(data)
@@ -156,8 +167,12 @@ class EventSerializer(I18nAwareModelSerializer):
meta_data = validated_data.pop('meta_data', None)
validated_data.pop('seat_category_mapping', None)
plugins = validated_data.pop('plugins', settings.PRETIX_PLUGINS_DEFAULT.split(','))
tz = validated_data.pop('timezone', None)
event = super().create(validated_data)
if tz:
event.settings.timezone = tz
# Meta data
if meta_data is not None:
for key, value in meta_data.items():
@@ -182,8 +197,12 @@ class EventSerializer(I18nAwareModelSerializer):
meta_data = validated_data.pop('meta_data', None)
plugins = validated_data.pop('plugins', None)
seat_category_mapping = validated_data.pop('seat_category_mapping', None)
tz = validated_data.pop('timezone', None)
event = super().update(instance, validated_data)
if tz:
event.settings.timezone = tz
# Meta data
if meta_data is not None:
current = {mv.property: mv for mv in event.meta_values.select_related('property')}
@@ -240,6 +259,7 @@ class CloneEventSerializer(EventSerializer):
is_public = validated_data.pop('is_public', None)
testmode = validated_data.pop('testmode', None)
has_subevents = validated_data.pop('has_subevents', None)
tz = validated_data.pop('timezone', None)
new_event = super().create(validated_data)
event = Event.objects.filter(slug=self.context['event'], organizer=self.context['organizer'].pk).first()
@@ -254,6 +274,8 @@ class CloneEventSerializer(EventSerializer):
if has_subevents is not None:
new_event.has_subevents = has_subevents
new_event.save()
if tz:
new_event.settings.timezone = tz
return new_event

View File

@@ -38,6 +38,7 @@ def event(organizer, meta_prop):
is_public=True
)
e.meta_values.create(property=meta_prop, value="Conference")
e.settings.timezone = 'Europe/Berlin'
return e

View File

@@ -76,6 +76,7 @@ TEST_EVENT_RES = {
"seating_plan": None,
"seat_category_mapping": {},
"meta_data": {"type": "Conference"},
'timezone': 'Europe/Berlin',
'plugins': [
'pretix.plugins.banktransfer',
'pretix.plugins.ticketoutputpdf'
@@ -174,7 +175,8 @@ def test_event_create(token_client, organizer, event, meta_prop):
"slug": "2030",
"meta_data": {
meta_prop.name: "Conference"
}
},
"timezone": "Europe/Amsterdam"
},
format='json'
)
@@ -185,6 +187,7 @@ def test_event_create(token_client, organizer, event, meta_prop):
property__name=meta_prop.name, value="Conference"
).exists()
assert organizer.events.get(slug="2030").plugins == settings.PRETIX_PLUGINS_DEFAULT
assert organizer.events.get(slug="2030").settings.timezone == "Europe/Amsterdam"
resp = token_client.post(
'/api/v1/organizers/{}/events/'.format(organizer.slug),
@@ -291,7 +294,8 @@ def test_event_create_with_clone(token_client, organizer, event, meta_prop):
},
"plugins": [
"pretix.plugins.ticketoutputpdf"
]
],
"timezone": "Europe/Vienna"
},
format='json'
)
@@ -305,6 +309,7 @@ def test_event_create_with_clone(token_client, organizer, event, meta_prop):
assert organizer.events.get(slug="2030").meta_values.filter(
property__name=meta_prop.name, value="Conference"
).exists()
assert cloned_event.settings.timezone == "Europe/Vienna"
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/clone/'.format(organizer.slug, event.slug),