summaryrefslogtreecommitdiff
path: root/ishtar_common/wizards.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/wizards.py')
-rw-r--r--ishtar_common/wizards.py121
1 files changed, 73 insertions, 48 deletions
diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py
index c5158dfcd..f522188a8 100644
--- a/ishtar_common/wizards.py
+++ b/ishtar_common/wizards.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -22,24 +22,27 @@ import logging
# from functools import wraps
from django.conf import settings
-from django.contrib.formtools.wizard.views import NamedUrlWizardView, \
- normalize_name, get_storage, StepsHelper
+from formtools.wizard.views import NamedUrlWizardView, normalize_name, \
+ get_storage, StepsHelper
+
from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.images import ImageFile
from django.core.files.storage import default_storage
from django.core.mail import send_mail
-from django.db.models.fields.files import FileField
+from django.db.models.fields.files import FileField, ImageFieldFile
from django.db.models.fields.related import ManyToManyField
from django.db.models.fields import NOT_PROVIDED
from django.http import HttpResponseRedirect
from django.forms import ValidationError
-from django.shortcuts import render_to_response, redirect
-from django.template import Context, RequestContext, loader
+from django.shortcuts import redirect, render
+from django.template import loader
from django.utils.datastructures import MultiValueDict as BaseMultiValueDict
from django.utils.translation import ugettext_lazy as _
-import models
+
+from ishtar_common import models
+from ishtar_common.utils import get_all_field_names
logger = logging.getLogger(__name__)
@@ -127,8 +130,7 @@ class Wizard(NamedUrlWizardView):
label = ''
translated_keys = []
modification = None # True when the wizard modify an item
- storage_name = \
- 'django.contrib.formtools.wizard.storage.session.SessionStorage'
+ storage_name = 'formtools.wizard.storage.session.SessionStorage'
wizard_done_template = 'ishtar/wizard/wizard_done.html'
wizard_done_window = ''
wizard_confirm = 'ishtar/wizard/confirm_wizard.html'
@@ -276,6 +278,7 @@ class Wizard(NamedUrlWizardView):
# simulate a non empty data for form that might be
# valid when empty
prefixed_values['__non_empty_data'] = ''
+ self.prepare_serialization(prefixed_values)
storage.set_step_data(next_step, prefixed_values)
if step == next_step:
current_step_passed = True
@@ -357,7 +360,7 @@ class Wizard(NamedUrlWizardView):
if form_datas:
form_datas.append(("", "", "spacer"))
items = hasattr(base_form, 'fields') and \
- base_form.fields.keyOrder or cleaned_data.keys()
+ base_form.fields.keys() or cleaned_data.keys()
for key in items:
lbl = None
if key.startswith('hidden_'):
@@ -368,7 +371,7 @@ class Wizard(NamedUrlWizardView):
if hasattr(base_form, 'associated_labels') \
and key in base_form.associated_labels:
lbl = base_form.associated_labels[key]
- if not lbl:
+ if not lbl or key not in cleaned_data:
continue
value = cleaned_data[key]
if value is None or value == '':
@@ -528,7 +531,7 @@ class Wizard(NamedUrlWizardView):
for k in dct:
if k.startswith('pk'):
continue
- if k not in obj.__class__._meta.get_all_field_names():
+ if k not in get_all_field_names(obj.__class__):
continue
# False set to None for images and files
if not k.endswith('_id') and (
@@ -608,7 +611,7 @@ class Wizard(NamedUrlWizardView):
if 'pk' in dct:
dct.pop('pk')
# remove non relevant fields
- all_field_names = self.get_saved_model()._meta.get_all_field_names()
+ all_field_names = get_all_field_names(self.get_saved_model())
for k in dct.copy():
if not (k.endswith('_id') and k[:-3] in all_field_names) \
and k not in all_field_names and \
@@ -715,19 +718,22 @@ class Wizard(NamedUrlWizardView):
# check if there is no missing fields
# should be managed normally in forms but...
- if hasattr(model._meta, 'get_fields'): # django 1.8
- fields = model._meta.get_field()
- else:
- fields = model._meta.fields
+ fields = model._meta.get_fields()
- has_problemetic_null = [
- (field.name, field.default == NOT_PROVIDED)
- for field in fields
+
+ has_problemetic_null = False
+ for field in fields:
if (field.name not in value
- or not value[field.name])
- and not field.null and not field.blank
- and (not field.default
- or field.default == NOT_PROVIDED)]
+ or not value[field.name]) \
+ and (hasattr(field, 'null')
+ and not field.null) \
+ and (hasattr(field, 'blank')
+ and not field.blank) \
+ and (hasattr(field, 'default')
+ and (not field.default
+ or field.default == NOT_PROVIDED)):
+ has_problemetic_null = True
+ break
if has_problemetic_null:
continue
@@ -739,7 +745,9 @@ class Wizard(NamedUrlWizardView):
value.save() # force post_save
# check that an item is not add multiple times (forged forms)
if value not in related_model.all() and\
- hasattr(related_model, 'add'):
+ (not hasattr(related_model, 'through') or
+ not isinstance(value, related_model.through)):
+ # many to many and the value have been already managed
related_model.add(value)
# necessary to manage interaction between models like
# material_index management for baseitems
@@ -771,8 +779,7 @@ class Wizard(NamedUrlWizardView):
wizard_done_window = unicode(self.wizard_done_window)
if wizard_done_window:
dct['wizard_done_window'] = wizard_done_window
- res = render_to_response(self.wizard_done_template, dct,
- context_instance=RequestContext(self.request))
+ res = render(self.request, self.wizard_done_template, dct)
return return_object and (obj, res) or res
def get_deleted(self, keys):
@@ -876,7 +883,7 @@ class Wizard(NamedUrlWizardView):
frm = form.forms[0]
if frm:
# autofocus on first field
- first_field = frm.fields[frm.fields.keyOrder[0]]
+ first_field = frm.fields[frm.fields.keys()[0]]
attrs = first_field.widget.attrs
attrs.update({'autofocus': "autofocus"})
first_field.widget.attrs = attrs
@@ -984,6 +991,19 @@ class Wizard(NamedUrlWizardView):
data[key] = value
storage.set_step_data(form_key, data)
+ @classmethod
+ def prepare_serialization(cls, data):
+ """
+ Image and file cannot be passed as object
+ """
+ for k in data:
+ if isinstance(data[k], ImageFieldFile) \
+ or isinstance(data[k], FileField):
+ try:
+ data[k] = data[k].path
+ except ValueError:
+ data[k] = None
+
def session_get_value(self, form_key, key, multi=False, multi_value=False):
"""Get the value of a specific form"""
if not self.session_has_key(form_key, key, multi):
@@ -1112,9 +1132,9 @@ class Wizard(NamedUrlWizardView):
continue
if hasattr(value, 'pk'):
value = value.pk
- if value in (True, False) or \
- isinstance(value, FileField) or \
- isinstance(value, ImageFile):
+ if value in (True, False) \
+ or isinstance(value, ImageFieldFile) \
+ or isinstance(value, FileField):
initial[base_field] = value
elif value is not None:
initial[base_field] = unicode(value)
@@ -1164,8 +1184,7 @@ class SearchWizard(NamedUrlWizardView):
model = None
label = ''
modification = None # True when the wizard modify an item
- storage_name = \
- 'django.contrib.formtools.wizard.storage.session.SessionStorage'
+ storage_name = 'formtools.wizard.storage.session.SessionStorage'
def get_wizard_name(self):
"""
@@ -1241,9 +1260,8 @@ class DeletionWizard(Wizard):
obj.delete()
except ObjectDoesNotExist:
pass
- return render_to_response(
- 'ishtar/wizard/wizard_delete_done.html', {},
- context_instance=RequestContext(self.request))
+ return render(
+ self.request, 'ishtar/wizard/wizard_delete_done.html', {})
class ClosingWizard(Wizard):
@@ -1294,9 +1312,8 @@ class ClosingWizard(Wizard):
and hasattr(obj, 'end_date'):
obj.end_date = form.cleaned_data['end_date']
obj.save()
- return render_to_response(
- 'ishtar/wizard/wizard_closing_done.html', {},
- context_instance=RequestContext(self.request))
+ return render(
+ self.request, 'ishtar/wizard/wizard_closing_done.html', {})
class PersonWizard(Wizard):
@@ -1377,17 +1394,24 @@ class AccountWizard(Wizard):
if key.startswith('hidden_password'):
dct['password'] = dct.pop(key)
try:
- account = models.IshtarUser.objects.get(person=person)
+ account = models.IshtarUser.objects.get(person=person).user_ptr
account.username = dct['username']
account.email = dct['email']
except ObjectDoesNotExist:
now = datetime.datetime.now()
- account = models.IshtarUser(
- person=person, username=dct['username'], email=dct['email'],
+ account = models.User.objects.create(
+ username=dct['username'], email=dct['email'],
first_name=person.surname or '***',
last_name=person.name or '***',
is_staff=False, is_active=True, is_superuser=False,
- last_login=now, date_joined=now)
+ last_login=now, date_joined=now
+ )
+ ishtaruser = account.ishtaruser
+ old_person_pk = ishtaruser.person.pk
+ ishtaruser.person = person
+ ishtaruser.save()
+ models.Person.objects.get(pk=old_person_pk).delete()
+
if dct['password']:
account.set_password(dct['password'])
account.save()
@@ -1398,20 +1422,21 @@ class AccountWizard(Wizard):
app_name = site and ("Ishtar - " + site.name) \
or "Ishtar"
- context = Context({
+ context = {
'login': dct['username'],
'password': dct['password'],
'app_name': app_name,
'site': site and site.domain or ""
- })
+ }
t = loader.get_template('account_activation_email.txt')
- msg = t.render(context)
+ msg = t.render(context, self.request)
subject = _(u"[%(app_name)s] Account creation/modification") % {
"app_name": app_name}
send_mail(subject, msg, settings.ADMINS[0][1],
[dct['email']], fail_silently=True)
- res = render_to_response('ishtar/wizard/wizard_done.html', {},
- context_instance=RequestContext(self.request))
+ res = render(
+ self.request, 'ishtar/wizard/wizard_done.html', {},
+ )
return res
def get_form_kwargs(self, step=None):