考虑以下用例,我正在尝试实现。我正在使用Flask,Flask-SQLAlchemy将用户数据存储在SQLite数据库中,使用Flask-Admin来存储其文件管理功能。
流程如下:当用户登录时,他将进入管理模块的索引视图。但是当他登录时,他的用户名被添加到FileAdmin类初始化时使用的路径 - 想法是拥有用户目录,这是用户注册时由简单的shell命令创建的。因此,如果Flask中定义的根路径是“/ files /”,而我的用户名是“rudimk”,那么初始化文件admin时应该使用的路径应该是“/ files / rudimk”。
问题是,当应用程序启动时,没有会话,没有用户登录 - 但文件管理员已初始化,使用默认路径,在我们的示例中为“/ files /”。当用户登录时,无法重新初始化文件管理类,因为它位于请求上下文之外。我从flask-admin文档中查看了get_base_path(),但是我无法弄清楚它在这里是如何有用的。
非常感谢。谢谢!
编辑 - 添加了我正在使用的一些代码。请注意,在这里,我删除了auth,并通过在会话中添加用户名来模拟经过身份验证的会话。
import os
import os.path as op
from flask import Flask, session
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():
# Simulating a logged-in user by storing his/her username in the session.
session["username"]
return '<a href="/admin/">Click me to get to Admin!</a>'
if __name__ == '__main__':
# Create directory
username = session["username"]
path = op.join(op.dirname(__file__), 'files/%s' %username)
try:
os.mkdir(path)
except OSError:
pass
# Create admin interface
admin = admin.Admin(app)
admin.add_view(fileadmin.FileAdmin(path, '/files/%s' %username, name='Files'))
# Start app
app.run(debug=True)
答案 0 :(得分:3)
get_base_path方法在您需要做的事情上非常明确..
覆盖以自定义行为(每用户目录等)
所以,这就是你需要做的。您需要创建一个继承自FileAdmin的类,重写get_base_path()
方法,并使用THAT类而不是基础FileAdmin。如果您不熟悉方法的“覆盖”,那么您应该寻找一个Python面向对象的教程。
您创建的这个新类需要覆盖每个用户的get_base_path()
方法。所以,像... ...
class MyFileAdmin(FileAdmin):
def get_base_path(self):
path = FileAdmin.get_base_path(self)
if not current_user.is_anonymous():
return os.path.join(path, current_user.custom_path)
else:
return path
现在使用MyFileAdmin
代替FileAdmin
。我没有测试过这段代码,但希望这能让你走上正轨。
请注意,更改实际FileAdmin实例上的路径的原始计划不起作用。您创建一个FileAdmin实例,所有用户将使用相同的视图路由其请求。如果你试图这样做,你可能会遇到多线程问题。