考虑以下我要实现的用例。我正在使用Flask,Flask-SQLAlchemy将用户数据存储在SQLite数据库中,以及Flask-Admin,用于其文件管理功能。
流程是这样的:当用户登录时,他被带到管理模块的索引视图。但是,当他登录时,其用户名将添加到初始化FileAdmin类时使用的路径上-想法是拥有用户目录,该目录在用户注册时由简单的shell命令创建。因此,如果Flask中定义的根路径是“ / files /”,而我的用户名是“ rudimk”,那么初始化文件admin时应使用的路径应该是“ / files / rudimk”。
问题是,当应用程序启动时,没有会话,也没有用户登录-但使用默认路径初始化了文件admin,在我们的示例中为“ / files /”。用户登录后,无法重新初始化文件admin类,因为它在请求上下文之外。我从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)
最佳答案
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实例,所有用户的请求都将使用同一视图进行路由。如果尝试执行此操作,可能会遇到多线程问题。
关于flask - 请求后初始化flask-admin的fileadmin,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19390177/