Picture-Puzzle-website/venv/Lib/site-packages/flask_admin/actions.py

130 lines
3.7 KiB
Python

from flask import request, redirect
from flask_admin import tools
from flask_admin._compat import text_type
from flask_admin.helpers import get_redirect_target, flash_errors
def action(name, text, confirmation=None):
"""
Use this decorator to expose actions that span more than one
entity (model, file, etc)
:param name:
Action name
:param text:
Action text.
:param confirmation:
Confirmation text. If not provided, action will be executed
unconditionally.
"""
def wrap(f):
f._action = (name, text, confirmation)
return f
return wrap
class ActionsMixin(object):
"""
Actions mixin.
In some cases, you might work with more than one "entity" (model, file, etc) in
your admin view and will want to perform actions on a group of entities simultaneously.
In this case, you can add this functionality by doing this:
1. Add this mixin to your administrative view class
2. Call `init_actions` in your class constructor
3. Expose actions view
4. Import `actions.html` library and add call library macros in your template
"""
def __init__(self):
"""
Default constructor.
"""
self._actions = []
self._actions_data = {}
def init_actions(self):
"""
Initialize list of actions for the current administrative view.
"""
self._actions = []
self._actions_data = {}
for p in dir(self):
attr = tools.get_dict_attr(self, p)
if hasattr(attr, '_action'):
name, text, desc = attr._action
self._actions.append((name, text))
# TODO: Use namedtuple
# Reason why we need getattr here - what's in attr is not
# bound to the object.
self._actions_data[name] = (getattr(self, p), text, desc)
def is_action_allowed(self, name):
"""
Verify if action with `name` is allowed.
:param name:
Action name
"""
return True
def get_actions_list(self):
"""
Return a list and a dictionary of allowed actions.
"""
actions = []
actions_confirmation = {}
for act in self._actions:
name, text = act
if self.is_action_allowed(name):
actions.append((name, text_type(text)))
confirmation = self._actions_data[name][2]
if confirmation:
actions_confirmation[name] = text_type(confirmation)
return actions, actions_confirmation
def handle_action(self, return_view=None):
"""
Handle action request.
:param return_view:
Name of the view to return to after the request.
If not provided, will return user to the return url in the form
or the list view.
"""
form = self.action_form()
if self.validate_form(form):
# using getlist instead of FieldList for backward compatibility
ids = request.form.getlist('rowid')
action = form.action.data
handler = self._actions_data.get(action)
if handler and self.is_action_allowed(action):
response = handler[0](ids)
if response is not None:
return response
else:
flash_errors(form, message='Failed to perform action. %(error)s')
if return_view:
url = self.get_url('.' + return_view)
else:
url = get_redirect_target() or self.get_url('.index_view')
return redirect(url)