summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@peacefrogs.net>2011-05-10 19:19:35 +0200
committerÉtienne Loks <etienne.loks@peacefrogs.net>2011-05-10 19:19:35 +0200
commit0c433b1deac28270dd24879fe4e34d18a8af3825 (patch)
tree802b2b000e0e5c9285a675122341cd738098107f
parent46f7600fb07064da04f8e8cf9af3fb1b74dbff3e (diff)
downloadIshtar-0c433b1deac28270dd24879fe4e34d18a8af3825.tar.bz2
Ishtar-0c433b1deac28270dd24879fe4e34d18a8af3825.zip
Better management of formset deletion (closes #350)
-rw-r--r--ishtar/furnitures/forms.py91
1 files changed, 62 insertions, 29 deletions
diff --git a/ishtar/furnitures/forms.py b/ishtar/furnitures/forms.py
index 5553be28c..390af17f8 100644
--- a/ishtar/furnitures/forms.py
+++ b/ishtar/furnitures/forms.py
@@ -247,7 +247,7 @@ class Wizard(NamedUrlSessionFormWizard):
"""
Save to the model
"""
- dct, m2m = {}, []
+ dct, m2m, whole_associated_models = {}, [], []
for form in form_list:
if not form.is_valid():
return self.render(request, storage, form)
@@ -258,6 +258,10 @@ class Wizard(NamedUrlSessionFormWizard):
multi = False
if form.forms:
frm = form.forms[0]
+ if hasattr(frm, 'base_model') and frm.base_model:
+ whole_associated_models.append(frm.base_model)
+ else:
+ whole_associated_models += associated_models.keys()
fields = frm.fields.copy()
if 'DELETE' in fields:
fields.pop('DELETE')
@@ -296,8 +300,8 @@ class Wizard(NamedUrlSessionFormWizard):
else:
value = None
dct[key] = value
- return self.save_model(dct, m2m, request, storage, form_list,
- return_object)
+ return self.save_model(dct, m2m, whole_associated_models, request,
+ storage, form_list, return_object)
def get_saved_model(self):
"""
@@ -311,7 +315,8 @@ class Wizard(NamedUrlSessionFormWizard):
"""
return self.get_current_object(request, storage)
- def save_model(self, dct, m2m, request, storage, form_list, return_object):
+ def save_model(self, dct, m2m, whole_associated_models, request, storage,
+ form_list, return_object):
dct = self.get_extra_model(dct, request, storage, form_list)
obj = self.get_current_saved_object(request, storage)
@@ -369,9 +374,11 @@ class Wizard(NamedUrlSessionFormWizard):
# material_index management for baseitems
obj.save()
m2m_items = {}
+ for model in whole_associated_models:
+ getattr(obj, model+'s').clear()
for key, value in m2m:
if key not in m2m_items:
- getattr(obj, key+'s').clear()
+ #getattr(obj, key+'s').clear()
if type(key) == dict:
vals = []
for item in getattr(obj, key+'s').all():
@@ -397,6 +404,29 @@ class Wizard(NamedUrlSessionFormWizard):
context_instance=RequestContext(request))
return return_object and (obj, res) or res
+ def get_deleted(self, keys):
+ """
+ Get the deleted and non-deleted items in formsets
+ """
+ not_to_delete, to_delete = set(), set()
+ for key in keys:
+ items = key.split('-')
+ if len(items) < 2 or items[-2] in to_delete:
+ continue
+ idx = items[-2]
+ try:
+ int(idx)
+ except:
+ continue
+ if items[-1] == u'DELETE':
+ to_delete.add(idx)
+ if idx in not_to_delete:
+ not_to_delete.remove(idx)
+ elif idx not in not_to_delete:
+ not_to_delete.add(idx)
+ return (to_delete, not_to_delete)
+
+
def get_form(self, request, storage, step=None, data=None, files=None):
"""
Manage formset
@@ -408,30 +438,25 @@ class Wizard(NamedUrlSessionFormWizard):
form = self.get_form_list(request, storage)[step]
if hasattr(form, 'management_form'):
# manage deletion
- not_to_delete, to_delete = [], []
+ to_delete, not_to_delete = self.get_deleted(data.keys())
+ # raz deleted fields
for key in data.keys():
items = key.split('-')
- if len(items) == 4:
- if items[2] not in to_delete and \
- items[2] not in not_to_delete:
- del_key = "-".join(items[:3]+["DELETE"])
- if del_key in data and data[del_key]:
- to_delete.append(items[2])
- else:
- not_to_delete.append(items[2])
- if items[2] in to_delete:
- data.pop(key)
+ if len(items) < 2 or items[-2] not in to_delete:
+ continue
+ data.pop(key)
if to_delete:
# reorganize
for idx, number in enumerate(sorted(not_to_delete)):
- if unicode(idx) == number:
+ idx = unicode(idx)
+ if idx == number:
continue
for key in data.keys():
items = key.split('-')
- if len(items) == 3 and items[1] == number:
- ck = '-'.join([items[0], unicode(idx),
- items[2]])
- data[ck] = data.pop(key)[0]
+ if len(items) > 2 and number == items[-2]:
+ items[-2] = unicode(idx)
+ k = u'-'.join(items)
+ data[k] = data.pop(key)[0]
# get a form key
base_key = form.form.base_fields.keys()[0]
init = self.get_form_initial(request, storage, step)
@@ -462,15 +487,15 @@ class Wizard(NamedUrlSessionFormWizard):
"""
Convert numerical step number to step name
"""
+ post_data = request.POST.copy()
if request.POST.has_key('form_prev_step'):
try:
step_number = int(request.POST['form_prev_step'])
- post_data = request.POST.copy()
post_data['form_prev_step'] = self.get_form_list(request,
storage).keys()[step_number]
- request.POST = post_data
except ValueError:
pass
+ request.POST = post_data
return super(Wizard, self).process_post_request(request, storage, *args,
**kwargs)
@classmethod
@@ -565,6 +590,9 @@ class Wizard(NamedUrlSessionFormWizard):
obj_name = prefixes[-2]
request.session[obj_name] = unicode(obj.pk)
initial = {}
+ if request.POST or (step in request.session[storage.prefix] and\
+ request.session[storage.prefix]['step_data'][step]):
+ return {}
if hasattr(c_form, 'base_fields'):
for base_field in c_form.base_fields.keys():
fields = base_field.split('__')
@@ -588,9 +616,11 @@ class Wizard(NamedUrlSessionFormWizard):
key = current_step.split('-')[0]
if not hasattr(obj, key):
return initial
- for child_obj in getattr(obj, key).all():
+ keys = c_form.form.base_fields.keys()
+ for child_obj in getattr(obj, key).order_by('pk').all():
+ if not keys:
+ break
vals = {}
- keys = c_form.form.base_fields.keys()
if len(keys) == 1:
# only one field: must be the id of the object
vals[keys[0]] = unicode(child_obj.pk)
@@ -846,6 +876,7 @@ class FileWizard(Wizard):
if type(r) not in (list, tuple) or len(r) != 2:
return r
obj, res = r
+ obj.parcels.clear()
for form in form_list:
if not hasattr(form, 'prefix') \
or not form.prefix.startswith('parcels-') \
@@ -1243,7 +1274,8 @@ class FileAdministrativeActWizard(FileWizard):
def get_associated_item(self, request, storage, dct):
return self.get_current_object(request, storage)
- def save_model(self, dct, m2m, request, storage, form_list, return_object):
+ def save_model(self, dct, m2m, whole_associated_models, request, storage,
+ form_list, return_object):
associated_item = self.get_associated_item(request, storage, dct)
if not associated_item:
return self.render(request, storage, form_list[-1])
@@ -1826,11 +1858,12 @@ class RecordWizard(Wizard):
return None
return self.get_current_object(request, storage)
- def save_model(self, dct, m2m, request, storage, form_list, return_object):
+ def save_model(self, dct, m2m, whole_associated_models, request, storage,
+ form_list, return_object):
if 'pk' in dct:
dct.pop('pk')
- return super(RecordWizard, self).save_model(dct, m2m, request, storage,
- form_list, return_object)
+ return super(RecordWizard, self).save_model(dct, m2m,
+ whole_associated_models, request, storage, form_list, return_object)
class RecordModifWizard(RecordWizard):
model = models.ContextRecord