129 lines
4.2 KiB
Python
129 lines
4.2 KiB
Python
import logging
|
|
from django import forms
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
from .. import converters
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ChainedForm(forms.Form):
|
|
_form_title = None
|
|
_initial_form_name = None
|
|
_next_form_name = None
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self._session_data = dict()
|
|
self._request = kwargs.pop('request', None)
|
|
self._load_session_data()
|
|
|
|
if 'initial' not in kwargs:
|
|
kwargs['initial'] = self._session_data
|
|
else:
|
|
kwargs['initial'].update(self._session_data)
|
|
|
|
super(ChainedForm, self).__init__(*args, **kwargs)
|
|
|
|
self._proceed_session_data(self._session_data)
|
|
|
|
def _serialize_value(self, value):
|
|
return converters.Iso8601Serializer.serialize(value, ignore_unsupported_input=True)
|
|
|
|
def _deserialize_value(self, value):
|
|
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 _get_model(self):
|
|
if not hasattr(self, '_model'):
|
|
raise ImproperlyConfigured('{cls} is missing a Model.'
|
|
' Define {cls}._model'.format(cls=self.__class__.__name__))
|
|
return self._model
|
|
|
|
def _get_object(self, model_kwargs):
|
|
return self._get_model()(**model_kwargs)
|
|
|
|
@property
|
|
def form_name(self):
|
|
return self.__class__.__name__
|
|
|
|
@property
|
|
def form_title(self):
|
|
return self.__class__.get_form_title()
|
|
|
|
@property
|
|
def initial_form_name(self):
|
|
return self.__class__.get_initial_form_name()
|
|
|
|
@property
|
|
def next_form_name(self):
|
|
return self.__class__.get_next_form_name()
|
|
|
|
@classmethod
|
|
def get_form_name(cls):
|
|
return cls.__name__
|
|
|
|
@classmethod
|
|
def get_form_title(cls):
|
|
if cls._form_title is not None:
|
|
return cls._form_title
|
|
n = cls.get_form_name()
|
|
if n.endswith('Form'):
|
|
n = n[:-len('Form')]
|
|
return n
|
|
|
|
@classmethod
|
|
def get_initial_form_name(cls):
|
|
return cls._initial_form_name or cls.__name__
|
|
|
|
@classmethod
|
|
def get_next_form_name(cls):
|
|
return cls._next_form_name
|
|
|
|
def clean(self):
|
|
cleaned_data = super(ChainedForm, self).clean()
|
|
self._session_data.update(cleaned_data)
|
|
self._save_session_data()
|
|
return cleaned_data
|
|
|
|
def save(self):
|
|
object_kwargs = dict()
|
|
data = self._session_data.copy()
|
|
if 'deadline' in data:
|
|
buf = data['deadline']
|
|
if isinstance(buf, basestring):
|
|
deadline_choice = buf.lower()
|
|
deadline_field = 'deadline_{}'.format(deadline_choice)
|
|
if deadline_field in data:
|
|
data['deadline'] = data[deadline_field]
|
|
|
|
model = self._get_model()
|
|
for field in data:
|
|
if hasattr(model, field):
|
|
object_kwargs[field] = data[field]
|
|
|
|
return self._get_object(object_kwargs)
|
|
|
|
def flush_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)
|
|
if session_var_name in self._request.session:
|
|
del self._request.session[session_var_name]
|
|
self._session_data = dict()
|