Add basic merge feature to MasterView
This commit is contained in:
parent
a398a0a710
commit
06b0b13992
3 changed files with 251 additions and 4 deletions
|
@ -55,6 +55,7 @@ class MasterView(View):
|
|||
viewable = True
|
||||
editable = True
|
||||
deletable = True
|
||||
mergeable = False
|
||||
|
||||
listing = False
|
||||
creating = False
|
||||
|
@ -394,6 +395,70 @@ class MasterView(View):
|
|||
'instance_title': instance_title,
|
||||
'form': form})
|
||||
|
||||
def get_merge_fields(self):
|
||||
if hasattr(self, 'merge_fields'):
|
||||
return self.merge_fields
|
||||
|
||||
def get_merge_coalesce_fields(self):
|
||||
if hasattr(self, 'merge_coalesce_fields'):
|
||||
return self.merge_coalesce_fields
|
||||
return []
|
||||
|
||||
def merge(self):
|
||||
"""
|
||||
Preview and execute a merge of two records.
|
||||
"""
|
||||
object_to_remove = object_to_keep = None
|
||||
if self.request.method == 'POST':
|
||||
uuids = self.request.POST.get('uuids', '').split(',')
|
||||
if len(uuids) == 2:
|
||||
object_to_remove = self.Session.query(self.get_model_class()).get(uuids[0])
|
||||
object_to_keep = self.Session.query(self.get_model_class()).get(uuids[1])
|
||||
|
||||
if object_to_remove and object_to_keep and self.request.POST.get('commit-merge') == 'yes':
|
||||
msg = unicode(object_to_remove)
|
||||
try:
|
||||
self.validate_merge(object_to_remove, object_to_keep)
|
||||
except Exception as error:
|
||||
self.request.session.flash("Requested merge cannot proceed (maybe swap keep/remove and try again?): {}".format(error), 'error')
|
||||
else:
|
||||
self.merge_objects(object_to_remove, object_to_keep)
|
||||
self.request.session.flash("{} has been merged into {}".format(msg, object_to_keep))
|
||||
return self.redirect(self.get_action_url('view', object_to_keep))
|
||||
|
||||
if not object_to_remove or not object_to_keep or object_to_remove is object_to_keep:
|
||||
return self.redirect(self.get_index_url())
|
||||
|
||||
remove = self.get_merge_data(object_to_remove)
|
||||
keep = self.get_merge_data(object_to_keep)
|
||||
return self.render_to_response('merge', {'object_to_remove': object_to_remove,
|
||||
'object_to_keep': object_to_keep,
|
||||
'view_url': lambda obj: self.get_action_url('view', obj),
|
||||
'merge_fields': self.get_merge_fields(),
|
||||
'remove_data': remove,
|
||||
'keep_data': keep,
|
||||
'resulting_data': self.get_merge_resulting_data(remove, keep)})
|
||||
|
||||
def validate_merge(self, removing, keeping):
|
||||
"""
|
||||
If applicable, your view should override this in order to confirm that
|
||||
the requested merge is valid, in your context. If it is not - for *any
|
||||
reason* - you should raise an exception; the type does not matter.
|
||||
"""
|
||||
|
||||
def get_merge_data(self, obj):
|
||||
raise NotImplementedError("please implement `{}.get_merge_data()`".format(self.__class__.__name__))
|
||||
|
||||
def get_merge_resulting_data(self, remove, keep):
|
||||
result = dict(keep)
|
||||
for field in self.get_merge_coalesce_fields():
|
||||
if remove[field] and not keep[field]:
|
||||
result[field] = remove[field]
|
||||
return result
|
||||
|
||||
def merge_objects(self, removing, keeping):
|
||||
raise NotImplementedError("please implement `{}.merge_objects()`".format(self.__class__.__name__))
|
||||
|
||||
##############################
|
||||
# Core Stuff
|
||||
##############################
|
||||
|
@ -635,7 +700,8 @@ class MasterView(View):
|
|||
'default_sortkey': getattr(self, 'default_sortkey', None),
|
||||
'sortdir': getattr(self, 'sortdir', 'asc'),
|
||||
'pageable': self.pageable,
|
||||
'checkboxes': self.checkboxes,
|
||||
'checkboxes': self.checkboxes or (
|
||||
self.mergeable and self.request.has_perm('{}.merge'.format(self.get_permission_prefix()))),
|
||||
'checked': self.checked,
|
||||
'row_attrs': self.get_row_attrs,
|
||||
'cell_attrs': self.get_cell_attrs,
|
||||
|
@ -662,8 +728,12 @@ class MasterView(View):
|
|||
defined; it depends on the type of data the grid deals with.
|
||||
"""
|
||||
if callable(self.row_attrs):
|
||||
return self.row_attrs(row, i)
|
||||
return self.row_attrs
|
||||
attrs = self.row_attrs(row, i)
|
||||
else:
|
||||
attrs = dict(self.row_attrs)
|
||||
if self.mergeable:
|
||||
attrs['data-uuid'] = row.uuid
|
||||
return attrs
|
||||
|
||||
def get_cell_attrs(self, row, column):
|
||||
"""
|
||||
|
@ -1142,6 +1212,14 @@ class MasterView(View):
|
|||
config.add_tailbone_permission(permission_prefix, '{0}.create'.format(permission_prefix),
|
||||
"Create new {0}".format(model_title))
|
||||
|
||||
# merge
|
||||
if cls.mergeable:
|
||||
config.add_route('{}.merge'.format(route_prefix), '{}/merge'.format(url_prefix))
|
||||
config.add_view(cls, attr='merge', route_name='{}.merge'.format(route_prefix),
|
||||
permission='{}.merge'.format(permission_prefix))
|
||||
config.add_tailbone_permission(permission_prefix, '{}.merge'.format(permission_prefix),
|
||||
"Merge 2 {}".format(model_title_plural))
|
||||
|
||||
# view
|
||||
if cls.viewable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.view'.format(permission_prefix),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue