from flask import Flask
from flask.ext import admin
# Create custom admin view
class MyAdminView(admin.BaseView):
@admin.expose('/')
def index(self):
return self.render('myadmin.html')
class AnotherAdminView(admin.BaseView):
@admin.expose('/')
def index(self):
return self.render('anotheradmin.html')
@admin.expose('/test/')
def test(self):
return self.render('test.html')
# Create flask app
app = Flask(__name__, template_folder='templates')
app.debug = True
# Flask views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
# Create admin interface
admin = admin.Admin()
admin.add_view(MyAdminView(category='Test'))
admin.add_view(AnotherAdminView(category='Test'))
admin.init_app(app)
if __name__ == '__main__':
# Start app
app.run()
class MenuItem(object):
"""
Simple menu tree hierarchy.
"""
def __init__(self, name, view=None):
self.name = name
self._view = view
self._children = []
self._children_urls = set()
self._cached_url = None
self.url = None
if view is not None:
self.url = view.url
def add_child(self, view):
self._children.append(view)
self._children_urls.add(view.url)
class Admin(object):
def __init__(self, app=None, name=None,
url=None, subdomain=None,
index_view=None,
translations_path=None,
endpoint=None,
static_url_path=None,
base_template=None):
self.app = app
self.translations_path = translations_path
self._views = []
self._menu = []
self._menu_categories = dict()
self._menu_links = []
if name is None:
name = 'Admin'
self.name = name
self.index_view = index_view or AdminIndexView(endpoint=endpoint, url=url)
self.endpoint = endpoint or self.index_view.endpoint
self.url = url or self.index_view.url
self.static_url_path = static_url_path
self.subdomain = subdomain
self.base_template = base_template or 'admin/base.html'
# Add predefined index view
self.add_view(self.index_view)
# Register with application
if app is not None:
self._init_extension()
def add_view(self, view):
# Add to views
self._views.append(view)
# If app was provided in constructor, register view with Flask app
if self.app is not None:
self.app.register_blueprint(view.create_blueprint(self))
self._add_view_to_menu(view)
def _add_view_to_menu(self, view):
if view.category:
category = self._menu_categories.get(view.category)
if category is None:
category = MenuItem(view.category)
self._menu_categories[view.category] = category
self._menu.append(category)
category.add_child(MenuItem(view.name, view))
else:
self._menu.append(MenuItem(view.name, view))
def init_app(self, app):
self.app = app
self._init_extension()
# Register views
for view in self._views:
app.register_blueprint(view.create_blueprint(self))
self._add_view_to_menu(view)
import os
import os.path as op
from flask import Flask
from flask.ext import admin
from flask.ext.admin.contrib import fileadmin
# Create flask app
app = Flask(__name__, template_folder='templates', static_folder='files')
# Create dummy secrey key so we can use flash
app.config['SECRET_KEY'] = '123456790'
# Flask views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
if __name__ == '__main__':
# Create directory
path = op.join(op.dirname(__file__), 'files')
try:
os.mkdir(path)
except OSError:
pass
# Create admin interface
admin = admin.Admin(app)
admin.add_view(fileadmin.FileAdmin(path, '/files/', name='Files'))
# Start app
app.run(debug=True)
def __init__(self, base_path, base_url,
name=None, category=None, endpoint=None, url=None,
verify_path=True):
self.init_actions()
@expose('/action/', methods=('POST',))
def action_view(self):
return self.handle_action()
# Actions
@action('delete',
lazy_gettext('Delete'),
lazy_gettext('Are you sure you want to delete these files?'))
def action_delete(self, items):
if not self.can_delete:
flash(gettext('File deletion is disabled.'), 'error')
return
for path in items:
base_path, full_path, path = self._normalize_path(path)
if self.is_accessible_path(path):
try:
os.remove(full_path)
flash(gettext('File "%(name)s" was successfully deleted.', name=path))
except Exception as ex:
flash(gettext('Failed to delete file: %(name)s', name=ex), 'error')
@action('edit', lazy_gettext('Edit'))
def action_edit(self, items):
return redirect(url_for('.edit', path=items))
@action()用于wrap跟在后面的函数,这里的作用就是把参数保存起来:
def action(name, text, confirmation=None)
def wrap(f):
f._action = (name, text, confirmation)
return f
return wrap
# 调试信息
_actions = [('delete', lu'Delete'), ('edit', lu'Edit')]
_actions_data = {'edit': (<bound method FileAdmin.action_edit of <flask_admin.contrib.fileadmin.FileAdmin object at 0x1aafc50>>, lu'Edit', None), 'delete': (<bound method FileAdmin.action_delete of <flask_admin.contrib.fileadmin.FileAdmin object at 0x1aafc50>>, lu'Delete', lu'Are you sure you want to delete these files?')}
# 省略无关代码
def handle_action(self, return_view=None):
action = request.form.get('action')
ids = request.form.getlist('rowid')
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
if not return_view:
url = url_for('.' + self._default_view)
else:
url = url_for('.' + return_view)
return redirect(url)
# 调试信息 ids: [u'1.png', u'2.png']
{% if actions %}
<div class="btn-group">
{{ actionslib.dropdown(actions, 'dropdown-toggle btn btn-large') }}
</div>
{% endif %}
{% block actions %}
{{ actionslib.form(actions, url_for('.action_view')) }}
{% endblock %}
{% block tail %}
{{ actionslib.script(_gettext('Please select at least one file.'),
actions,
actions_confirmation) }}
{% endblock %}
{% macro dropdown(actions, btn_class='dropdown-toggle') -%}
<a class="{{ btn_class }}" data-toggle="dropdown" href="javascript:void(0)">{{ _gettext('With selected') }}<b class="caret"></b></a>
<ul class="dropdown-menu">
{% for p in actions %}
<li>
<a href="javascript:void(0)" onclick="return modelActions.execute('{{ p[0] }}');">{{ _gettext(p[1]) }}</a>
</li>
{% endfor %}
</ul>
{% endmacro %}
{% macro form(actions, url) %}
{% if actions %}
<form id="action_form" action="{{ url }}" method="POST" style="display: none">
{% if csrf_token %}
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
{% endif %}
<input type="hidden" id="action" name="action" />
</form>
{% endif %}
{% endmacro %}
{% macro script(message, actions, actions_confirmation) %}
{% if actions %}
<script src="{{ admin_static.url(filename='admin/js/actions.js') }}"></script>
<script language="javascript">
var modelActions = new AdminModelActions({{ message|tojson|safe }}, {{ actions_confirmation|tojson|safe }});
</script>
{% endif %}
{% endmacro %}
<div class="btn-group">
<a class="dropdown-toggle btn btn-large" href="javascript:void(0)" data-toggle="dropdown">
With selected
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li>
<a onclick="return modelActions.execute('delete');" href="javascript:void(0)">Delete</a>
</li>
<li>
<a onclick="return modelActions.execute('edit');" href="javascript:void(0)">Edit</a>
</li>
</ul>
</div>
<form id="action_form" action="/admin/fileadmin/action/" method="POST" style="display: none">
<input type="hidden" id="action" name="action" />
</form>
<script src="/admin/static/admin/js/actions.js"></script>
<script language="javascript">
var modelActions = new AdminModelActions("Please select at least one file.", {"delete": "Are you sure you want to delete these files?"});
</script>
var AdminModelActions = function(actionErrorMessage, actionConfirmations) {
// Actions helpers. TODO: Move to separate file
this.execute = function(name) {
var selected = $('input.action-checkbox:checked').size();
if (selected === 0) {
alert(actionErrorMessage);
return false;
}
var msg = actionConfirmations[name];
if (!!msg)
if (!confirm(msg))
return false;
// Update hidden form and submit it
var form = $('#action_form');
$('#action', form).val(name);
$('input.action-checkbox', form).remove();
$('input.action-checkbox:checked').each(function() {
form.append($(this).clone());
});
form.submit();
return false;
};
$(function() {
$('.action-rowtoggle').change(function() {
$('input.action-checkbox').attr('checked', this.checked);
});
});
};
# 初始化 <form id="action_form" style="display: none" method="POST" action="/admin/fileadmin/action/"> <input id="action" type="hidden" name="action"> </form> # 'Delete'选中的三个文件 <form id="action_form" style="display: none" method="POST" action="/admin/fileadmin/action/"> <input id="action" type="hidden" name="action" value="delete"> <input class="action-checkbox" type="checkbox" value="1.png" name="rowid"> <input class="action-checkbox" type="checkbox" value="2.png" name="rowid"> <input class="action-checkbox" type="checkbox" value="3.png" name="rowid"> </form> # 'Edit'选中的一个文件 <form id="action_form" style="display: none" method="POST" action="/admin/fileadmin/action/"> <input id="action" type="hidden" name="action" value="edit"> <input class="action-checkbox" type="checkbox" value="1.png" name="rowid"> </form>
class MyModelView(BaseModelView): column_formatters = dict(price=lambda v, c, m, p: m.price*2)
from flask.ext.admin.model.template import macro
class MyModelView(BaseModelView):
column_formatters = dict(price=macro('render_price'))
# in template
{% macro render_price(model, column) %}
{{ model.price * 2 }}
{% endmacro %}
def formatter(view, context, model, name): # `view` is current administrative view # `context` is instance of jinja2.runtime.Context # `model` is model instance # `name` is property name pass
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有