Finalized copy event feature.
This commit is contained in:
3
TODO.txt
3
TODO.txt
@@ -1,12 +1,11 @@
|
|||||||
- Save as Draft
|
- Save as Draft
|
||||||
- Copy Event
|
|
||||||
- Tourenreferent managed Gruppen der Subreferenten
|
- Tourenreferent managed Gruppen der Subreferenten
|
||||||
- Placeholder von forms in config/app_config
|
- Placeholder von forms in config/app_config
|
||||||
|
|
||||||
- Besserer Zurück-Button in Formulare
|
- Besserer Zurück-Button in Formulare
|
||||||
- uhrzeitfelder ohne widget
|
- uhrzeitfelder ohne widget
|
||||||
- vorbereitung: textfeld beschreibung einleitung, so dass beschreibung nur auf webseite geht.
|
- vorbereitung: textfeld beschreibung einleitung, so dass beschreibung nur auf webseite geht.
|
||||||
- kontaktdaten für 2. und 3. trainer wieder weg
|
- kontaktdaten für 2. und 3. trainer wieder weg?
|
||||||
- erster teil des anmeldungshowto editierbar
|
- erster teil des anmeldungshowto editierbar
|
||||||
- publizierendes feld für redaktionellen hinweis
|
- publizierendes feld für redaktionellen hinweis
|
||||||
- vortreffen ohne datum?
|
- vortreffen ohne datum?
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from babel.dates import format_date
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.utils.translation import get_language, ugettext, ugettext_lazy as _
|
from django.utils.translation import get_language, ugettext, ugettext_lazy as _
|
||||||
from django_countries.fields import LazyTypedChoiceField
|
from django_countries.fields import Country, LazyTypedChoiceField
|
||||||
from datetimewidget.widgets import DateWidget, TimeWidget, DateTimeWidget
|
from datetimewidget.widgets import DateWidget, TimeWidget, DateTimeWidget
|
||||||
|
|
||||||
from .. import choices
|
from .. import choices
|
||||||
@@ -80,6 +80,12 @@ class EventCreateForm(ModelMixin, ChainedForm):
|
|||||||
_model = models.Event
|
_model = models.Event
|
||||||
_initial_form_name = 'ModeForm'
|
_initial_form_name = 'ModeForm'
|
||||||
|
|
||||||
|
def _serialize_value(self, value):
|
||||||
|
r = super(EventCreateForm, self)._serialize_value(value)
|
||||||
|
if isinstance(r, Country):
|
||||||
|
r = r.code
|
||||||
|
return r
|
||||||
|
|
||||||
def _get_instance_kwargs(self):
|
def _get_instance_kwargs(self):
|
||||||
kwargs = self._session_data.copy()
|
kwargs = self._session_data.copy()
|
||||||
if 'deadline' in kwargs:
|
if 'deadline' in kwargs:
|
||||||
@@ -264,8 +270,8 @@ class LocationForm(EventCreateForm):
|
|||||||
label=_(u'Anderes Verkehrsmittel zur An- und Abreise'),
|
label=_(u'Anderes Verkehrsmittel zur An- und Abreise'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
def proceed_session_data(self, session_data):
|
||||||
super(LocationForm, self)._proceed_session_data(session_data)
|
super(LocationForm, self).proceed_session_data(session_data)
|
||||||
|
|
||||||
sport = session_data.get('sport', None)
|
sport = session_data.get('sport', None)
|
||||||
last_day = session_data.get('last_day', None)
|
last_day = session_data.get('last_day', None)
|
||||||
@@ -386,8 +392,8 @@ class JourneyForm(EventCreateForm):
|
|||||||
return 'AccommodationForm'
|
return 'AccommodationForm'
|
||||||
return super(JourneyForm, self).next_form_name
|
return super(JourneyForm, self).next_form_name
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
def proceed_session_data(self, session_data):
|
||||||
super(JourneyForm, self)._proceed_session_data(session_data)
|
super(JourneyForm, self).proceed_session_data(session_data)
|
||||||
|
|
||||||
first_day = session_data.get('first_day', None)
|
first_day = session_data.get('first_day', None)
|
||||||
last_day = session_data.get('last_day', None)
|
last_day = session_data.get('last_day', None)
|
||||||
@@ -438,8 +444,8 @@ class AccommodationForm(EventCreateForm):
|
|||||||
label=_(u'Andere Verpflegung'),
|
label=_(u'Andere Verpflegung'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
def proceed_session_data(self, session_data):
|
||||||
super(AccommodationForm, self)._proceed_session_data(session_data)
|
super(AccommodationForm, self).proceed_session_data(session_data)
|
||||||
self.fields['basecamp'].widget.attrs['placeholder'] = _(u'Kann freigelassen werden')
|
self.fields['basecamp'].widget.attrs['placeholder'] = _(u'Kann freigelassen werden')
|
||||||
self.fields['accommodation_other'].widget.attrs['placeholder'] = _(u'Nebenstehendes Feld beachten')
|
self.fields['accommodation_other'].widget.attrs['placeholder'] = _(u'Nebenstehendes Feld beachten')
|
||||||
self.fields['meals_other'].widget.attrs['placeholder'] = _(u'Nebenstehendes Feld beachten')
|
self.fields['meals_other'].widget.attrs['placeholder'] = _(u'Nebenstehendes Feld beachten')
|
||||||
@@ -548,8 +554,8 @@ class TrainerForm(EventCreateForm):
|
|||||||
help_text=_(u'Kann freigelassen werden'),
|
help_text=_(u'Kann freigelassen werden'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
def proceed_session_data(self, session_data):
|
||||||
super(TrainerForm, self)._proceed_session_data(session_data)
|
super(TrainerForm, self).proceed_session_data(session_data)
|
||||||
|
|
||||||
self.fields['trainer_firstname'].widget.attrs['placeholder'] = _(u'Vorname')
|
self.fields['trainer_firstname'].widget.attrs['placeholder'] = _(u'Vorname')
|
||||||
self.fields['trainer_familyname'].widget.attrs['placeholder'] = _(u'Nachname')
|
self.fields['trainer_familyname'].widget.attrs['placeholder'] = _(u'Nachname')
|
||||||
@@ -635,8 +641,8 @@ class RegistrationForm(EventCreateForm):
|
|||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
def proceed_session_data(self, session_data):
|
||||||
super(RegistrationForm, self)._proceed_session_data(session_data)
|
super(RegistrationForm, self).proceed_session_data(session_data)
|
||||||
|
|
||||||
first_day = session_data.get('first_day', None)
|
first_day = session_data.get('first_day', None)
|
||||||
|
|
||||||
@@ -705,8 +711,8 @@ class ChargesForm(EventCreateForm):
|
|||||||
return 'TrainingForm'
|
return 'TrainingForm'
|
||||||
return super(ChargesForm, self).next_form_name
|
return super(ChargesForm, self).next_form_name
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
def proceed_session_data(self, session_data):
|
||||||
super(ChargesForm, self)._proceed_session_data(session_data)
|
super(ChargesForm, self).proceed_session_data(session_data)
|
||||||
|
|
||||||
first_day = session_data.get('first_day', None)
|
first_day = session_data.get('first_day', None)
|
||||||
arrival_previous_day = session_data.get('arrival_previous_day', False)
|
arrival_previous_day = session_data.get('arrival_previous_day', False)
|
||||||
@@ -890,7 +896,7 @@ class SummaryForm(EventCreateForm):
|
|||||||
u' für Tourenreferenten und Redakteure eingeben.'),
|
u' für Tourenreferenten und Redakteure eingeben.'),
|
||||||
widget=forms.Textarea(attrs={'rows': 5}))
|
widget=forms.Textarea(attrs={'rows': 5}))
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
def proceed_session_data(self, session_data):
|
||||||
registration_required = self._session_data.get('registration_required', False)
|
registration_required = self._session_data.get('registration_required', False)
|
||||||
if registration_required:
|
if registration_required:
|
||||||
deadline = self._session_data.get('deadline', None)
|
deadline = self._session_data.get('deadline', None)
|
||||||
@@ -901,7 +907,7 @@ class SummaryForm(EventCreateForm):
|
|||||||
if deadline_field_name in self._session_data:
|
if deadline_field_name in self._session_data:
|
||||||
deadline = self._session_data.get(deadline_field_name)
|
deadline = self._session_data.get(deadline_field_name)
|
||||||
else:
|
else:
|
||||||
logger.error('SummaryForm._proceed_session_data(): invalid value for deadline.')
|
logger.error('SummaryForm.proceed_session_data(): invalid value for deadline.')
|
||||||
deadline = None
|
deadline = None
|
||||||
|
|
||||||
if deadline:
|
if deadline:
|
||||||
@@ -916,7 +922,7 @@ class SummaryForm(EventCreateForm):
|
|||||||
for year in (today.year, today.year + 1):
|
for year in (today.year, today.year + 1):
|
||||||
for issue in app_config.settings.publish_issues:
|
for issue in app_config.settings.publish_issues:
|
||||||
if not ('issue' in issue and 'release' in issue and 'deadline' in issue):
|
if not ('issue' in issue and 'release' in issue and 'deadline' in issue):
|
||||||
logger.error('SummaryForm._proceed_session_data(): invalid configured issue.')
|
logger.error('SummaryForm.proceed_session_data(): invalid configured issue.')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
issue_release = datetime.date(year, issue['release'][1], issue['release'][0])
|
issue_release = datetime.date(year, issue['release'][1], issue['release'][0])
|
||||||
|
|||||||
@@ -17,7 +17,13 @@ class ChainedForm(forms.Form):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._session_data = dict()
|
self._session_data = dict()
|
||||||
self._request = kwargs.pop('request', None)
|
self._request = kwargs.pop('request', None)
|
||||||
self._load_session_data()
|
self.load_session_data()
|
||||||
|
|
||||||
|
if 'instance' in kwargs:
|
||||||
|
if hasattr(self, 'load_from_instance'):
|
||||||
|
self._session_data.update(self.load_from_instance(kwargs.pop('instance')))
|
||||||
|
else:
|
||||||
|
raise TypeError('Keyword argument \'instance\' requires method \'load_from_instance\'')
|
||||||
|
|
||||||
if 'initial' not in kwargs:
|
if 'initial' not in kwargs:
|
||||||
kwargs['initial'] = self._session_data
|
kwargs['initial'] = self._session_data
|
||||||
@@ -26,7 +32,7 @@ class ChainedForm(forms.Form):
|
|||||||
|
|
||||||
super(ChainedForm, self).__init__(*args, **kwargs)
|
super(ChainedForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self._proceed_session_data(self._session_data)
|
self.proceed_session_data(self._session_data)
|
||||||
|
|
||||||
def _serialize_value(self, value):
|
def _serialize_value(self, value):
|
||||||
return converters.Iso8601Serializer.serialize(value, ignore_unsupported_input=True)
|
return converters.Iso8601Serializer.serialize(value, ignore_unsupported_input=True)
|
||||||
@@ -34,27 +40,9 @@ class ChainedForm(forms.Form):
|
|||||||
def _deserialize_value(self, value):
|
def _deserialize_value(self, value):
|
||||||
return converters.Iso8601Serializer.deserialize(value, ignore_unsupported_input=True)
|
return converters.Iso8601Serializer.deserialize(value, ignore_unsupported_input=True)
|
||||||
|
|
||||||
def _load_session_data(self):
|
|
||||||
if self._request is not None and hasattr(self._request, 'session'):
|
|
||||||
session_var_name = '{}_chained_form_session_data'.format(self._request.resolver_match.url_name)
|
|
||||||
session_data = self._request.session.get(session_var_name, dict())
|
|
||||||
for k in session_data:
|
|
||||||
self._session_data[k] = self._deserialize_value(session_data[k])
|
|
||||||
|
|
||||||
def _proceed_session_data(self, session_data):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _save_session_data(self):
|
|
||||||
if self._request is not None and hasattr(self._request, 'session'):
|
|
||||||
session_var_name = '{}_chained_form_session_data'.format(self._request.resolver_match.url_name)
|
|
||||||
session_data = dict()
|
|
||||||
for k in self._session_data:
|
|
||||||
session_data[k] = self._serialize_value(self._session_data[k])
|
|
||||||
self._request.session[session_var_name] = session_data
|
|
||||||
|
|
||||||
def _post_clean(self):
|
def _post_clean(self):
|
||||||
self._session_data.update(self.cleaned_data)
|
self._session_data.update(self.cleaned_data)
|
||||||
self._save_session_data()
|
self.save_session_data()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def form_name(self):
|
def form_name(self):
|
||||||
@@ -72,6 +60,10 @@ class ChainedForm(forms.Form):
|
|||||||
def next_form_name(self):
|
def next_form_name(self):
|
||||||
return self.__class__.get_next_form_name()
|
return self.__class__.get_next_form_name()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def session_data(self):
|
||||||
|
return self._session_data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_form_name(cls):
|
def get_form_name(cls):
|
||||||
return cls.__name__
|
return cls.__name__
|
||||||
@@ -102,6 +94,41 @@ class ChainedForm(forms.Form):
|
|||||||
value = app_config.settings.form_initials[form_name][field_name].get_value(self._session_data)
|
value = app_config.settings.form_initials[form_name][field_name].get_value(self._session_data)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def load_session_data(self, data=None, request=None):
|
||||||
|
if data is None:
|
||||||
|
if request is None:
|
||||||
|
if self._request is None:
|
||||||
|
logger.warning('ChainedForm.load_session_data(): Cannot access request.')
|
||||||
|
return
|
||||||
|
request = self._request
|
||||||
|
if not hasattr(request, 'session'):
|
||||||
|
logger.warning('ChainedForm.load_session_data(): Cannot access session.')
|
||||||
|
return
|
||||||
|
session_var_name = '{}_chained_form_session_data'.format(request.resolver_match.url_name)
|
||||||
|
data = request.session.get(session_var_name, dict())
|
||||||
|
for k in data:
|
||||||
|
self._session_data[k] = self._deserialize_value(data[k])
|
||||||
|
|
||||||
|
def save_session_data(self, request=None):
|
||||||
|
if request is None:
|
||||||
|
if self._request is None:
|
||||||
|
logger.warning('ChainedForm.save_session_data(): Cannot access request.')
|
||||||
|
return
|
||||||
|
request = self._request
|
||||||
|
if not hasattr(request, 'session'):
|
||||||
|
logger.warning('ChainedForm.save_session_data(): Cannot access session.')
|
||||||
|
return
|
||||||
|
|
||||||
|
session_var_name = '{}_chained_form_session_data'.format(request.resolver_match.url_name)
|
||||||
|
session_data = dict()
|
||||||
|
for k in self._session_data:
|
||||||
|
session_data[k] = self._serialize_value(self._session_data[k])
|
||||||
|
request.session[session_var_name] = session_data
|
||||||
|
return session_data
|
||||||
|
|
||||||
|
def proceed_session_data(self, session_data):
|
||||||
|
pass
|
||||||
|
|
||||||
def flush_session_data(self):
|
def flush_session_data(self):
|
||||||
if self._request is not None and hasattr(self._request, 'session'):
|
if self._request is not None and hasattr(self._request, 'session'):
|
||||||
session_var_name = '{}_chained_form_session_data'.format(self._request.resolver_match.url_name)
|
session_var_name = '{}_chained_form_session_data'.format(self._request.resolver_match.url_name)
|
||||||
@@ -135,10 +162,9 @@ class ModelMixin(object):
|
|||||||
model = self._get_model()
|
model = self._get_model()
|
||||||
if not isinstance(instance, model):
|
if not isinstance(instance, model):
|
||||||
raise TypeError('Expected %s' % model.__class__.__name__)
|
raise TypeError('Expected %s' % model.__class__.__name__)
|
||||||
self.is_bound = True
|
data = {}
|
||||||
self.data = {}
|
|
||||||
self.cleaned_data = {}
|
|
||||||
for field in instance._meta.get_fields():
|
for field in instance._meta.get_fields():
|
||||||
self.data[field.name] = getattr(instance, field.name)
|
data[field.name] = getattr(instance, field.name)
|
||||||
self.cleaned_data[field.name] = getattr(instance, field.name)
|
self.is_bound = True
|
||||||
self._post_clean()
|
self.data = data
|
||||||
|
return data
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
<div class="action-tabs">
|
<div class="action-tabs">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<a class="btn btn-primary"
|
<a class="btn btn-primary"
|
||||||
href="{% url 'dav_events:event_copy' event.pk %}"
|
href="{% url 'dav_events:event_create' %}?copy={{ event.pk }}"
|
||||||
title="{% trans 'Diese Veranstaltung als Vorlage für eine neue Veranstaltung benutzen' %}">
|
title="{% trans 'Diese Veranstaltung als Vorlage für eine neue Veranstaltung benutzen' %}">
|
||||||
{% bootstrap_icon 'duplicate' %} 
|
{% bootstrap_icon 'duplicate' %} 
|
||||||
{% trans 'Kopieren' %}
|
{% trans 'Kopieren' %}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ urlpatterns = [
|
|||||||
url(r'^events$', views.events.EventListView.as_view(), name='event_list'),
|
url(r'^events$', views.events.EventListView.as_view(), name='event_list'),
|
||||||
url(r'^events/export$', views.events.EventListExportView.as_view(), name='event_list_export'),
|
url(r'^events/export$', views.events.EventListExportView.as_view(), name='event_list_export'),
|
||||||
url(r'^events/create$', views.events.EventCreateView.as_view(), name='event_create'),
|
url(r'^events/create$', views.events.EventCreateView.as_view(), name='event_create'),
|
||||||
url(r'^events/(?P<pk>\d+)/copy', views.events.EventCopyView.as_view(), name='event_copy'),
|
|
||||||
url(r'^events/(?P<pk>\d+)/confirmpublication',
|
url(r'^events/(?P<pk>\d+)/confirmpublication',
|
||||||
views.events.EventConfirmPublicationView.as_view(), name='event_confirmpublication'),
|
views.events.EventConfirmPublicationView.as_view(), name='event_confirmpublication'),
|
||||||
url(r'^events/(?P<pk>\d+)/accept', views.events.EventAcceptView.as_view(), name='event_accept'),
|
url(r'^events/(?P<pk>\d+)/accept', views.events.EventAcceptView.as_view(), name='event_accept'),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from django.contrib.auth.decorators import login_required
|
|||||||
from django.core.exceptions import PermissionDenied, SuspiciousOperation
|
from django.core.exceptions import PermissionDenied, SuspiciousOperation
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
@@ -220,20 +221,7 @@ class EventUpdateView(EventPermissionMixin, generic.UpdateView):
|
|||||||
return super(EventUpdateView, self).dispatch(request, *args, **kwargs)
|
return super(EventUpdateView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class EventCopyView(EventDetailView):
|
class EventCreateView(EventPermissionMixin, generic.FormView):
|
||||||
permission = 'view'
|
|
||||||
form_class = forms.events.EventCreateForm
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
event = self.get_object()
|
|
||||||
initial_form_name = self.form_class.get_initial_form_name()
|
|
||||||
form_class = getattr(forms.events, initial_form_name)
|
|
||||||
form = form_class(request=self.request)
|
|
||||||
form.load_from_instance(event)
|
|
||||||
return HttpResponseRedirect(reverse('dav_events:event_create'))
|
|
||||||
|
|
||||||
|
|
||||||
class EventCreateView(generic.FormView):
|
|
||||||
form_class = forms.events.EventCreateForm
|
form_class = forms.events.EventCreateForm
|
||||||
template_dir = os.path.join('dav_events', 'event_create')
|
template_dir = os.path.join('dav_events', 'event_create')
|
||||||
default_template_name = 'default.html'
|
default_template_name = 'default.html'
|
||||||
@@ -313,6 +301,23 @@ class EventCreateView(generic.FormView):
|
|||||||
form = self.get_form()
|
form = self.get_form()
|
||||||
form.flush_session_data()
|
form.flush_session_data()
|
||||||
return HttpResponseRedirect(self.abort_url)
|
return HttpResponseRedirect(self.abort_url)
|
||||||
|
elif 'copy' in request.GET:
|
||||||
|
event = get_object_or_404(models.Event, pk=request.GET.get('copy'))
|
||||||
|
if not self.has_permission('view', event):
|
||||||
|
raise PermissionDenied('copy')
|
||||||
|
|
||||||
|
for field in ('id', 'owner', 'created_at',
|
||||||
|
'accepted_at', 'accepted_by',
|
||||||
|
'publication_confirmed_at', 'publication_confirmed_by',
|
||||||
|
'number'):
|
||||||
|
setattr(event, field, None)
|
||||||
|
for field in ('accepted', 'publication_confirmed'):
|
||||||
|
setattr(event, field, False)
|
||||||
|
|
||||||
|
initial_form_name = self.form_class.get_initial_form_name()
|
||||||
|
form_class = getattr(forms.events, initial_form_name)
|
||||||
|
form = form_class(request=self.request, instance=event)
|
||||||
|
form.save_session_data()
|
||||||
return super(EventCreateView, self).get(request, *args, **kwargs)
|
return super(EventCreateView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|||||||
Reference in New Issue
Block a user