forked from CGM_Public/pretix_original
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:
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user