Add "populatable" for master views (populating new objects with progress)
This commit is contained in:
parent
8a945f8baf
commit
47ce0fd448
|
@ -71,6 +71,7 @@ class MasterView(View):
|
|||
editable = True
|
||||
deletable = True
|
||||
bulk_deletable = False
|
||||
populatable = False
|
||||
mergeable = False
|
||||
downloadable = False
|
||||
cloneable = False
|
||||
|
@ -279,8 +280,74 @@ class MasterView(View):
|
|||
form.save()
|
||||
|
||||
def redirect_after_create(self, instance, mobile=False):
|
||||
if self.populatable and self.should_populate(instance):
|
||||
return self.redirect(self.get_action_url('populate', instance, mobile=mobile))
|
||||
return self.redirect(self.get_action_url('view', instance, mobile=mobile))
|
||||
|
||||
def should_populate(self, obj):
|
||||
return True
|
||||
|
||||
def populate(self):
|
||||
"""
|
||||
View for populating a new object. What exactly this means / does will
|
||||
depend on the logic in :meth:`populate_object()`.
|
||||
"""
|
||||
obj = self.get_instance()
|
||||
route_prefix = self.get_route_prefix()
|
||||
permission_prefix = self.get_permission_prefix()
|
||||
|
||||
# showing progress requires a separate thread; start that first
|
||||
key = '{}.populate'.format(route_prefix)
|
||||
progress = SessionProgress(self.request, key)
|
||||
thread = Thread(target=self.populate_thread, args=(obj.uuid, progress)) # TODO: uuid?
|
||||
thread.start()
|
||||
|
||||
# Send user to progress page.
|
||||
kwargs = {
|
||||
'cancel_url': self.get_action_url('view', obj),
|
||||
'cancel_msg': "{} population was canceled.".format(self.get_model_title()),
|
||||
}
|
||||
|
||||
return self.render_progress(progress, kwargs)
|
||||
|
||||
def populate_thread(self, uuid, progress): # TODO: uuid?
|
||||
"""
|
||||
Thread target for populating new object with progress indicator.
|
||||
"""
|
||||
# mustn't use tailbone web session here
|
||||
session = RattailSession()
|
||||
obj = session.query(self.model_class).get(uuid)
|
||||
try:
|
||||
self.populate_object(session, obj, progress=progress)
|
||||
except Exception as error:
|
||||
session.rollback()
|
||||
msg = "{} population failed".format(self.get_model_title())
|
||||
log.warning("{}: {}".format(msg, obj), exc_info=True)
|
||||
session.close()
|
||||
if progress:
|
||||
progress.session.load()
|
||||
progress.session['error'] = True
|
||||
progress.session['error_msg'] = "{}: {} {}".format(msg, error.__class__.__name__, error)
|
||||
progress.session.save()
|
||||
return
|
||||
|
||||
session.commit()
|
||||
session.refresh(obj)
|
||||
session.close()
|
||||
|
||||
# finalize progress
|
||||
if progress:
|
||||
progress.session.load()
|
||||
progress.session['complete'] = True
|
||||
progress.session['success_url'] = self.get_action_url('view', obj)
|
||||
progress.session.save()
|
||||
|
||||
def populate_object(self, session, obj, progress=None):
|
||||
"""
|
||||
You must define this if new objects require population.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def view(self, instance=None):
|
||||
"""
|
||||
View for viewing details of an existing model record.
|
||||
|
@ -1862,6 +1929,12 @@ class MasterView(View):
|
|||
config.add_view(cls, attr='mobile_create', route_name='mobile.{}.create'.format(route_prefix),
|
||||
permission='{}.create'.format(permission_prefix))
|
||||
|
||||
# populate new object
|
||||
if cls.populatable:
|
||||
config.add_route('{}.populate'.format(route_prefix), '{}/{{uuid}}/populate'.format(url_prefix))
|
||||
config.add_view(cls, attr='populate', route_name='{}.populate'.format(route_prefix),
|
||||
permission='{}.create'.format(permission_prefix))
|
||||
|
||||
# bulk delete
|
||||
if cls.bulk_deletable:
|
||||
config.add_route('{}.bulk_delete'.format(route_prefix), '{}/bulk-delete'.format(url_prefix))
|
||||
|
|
Loading…
Reference in a new issue