我正在尝试构建一个与Flask应用程序集成的Dash应用程序。一切似乎都正常,但是当我尝试在Dash应用中显示登录用户时,显示为“无”。
我的应用程序结构如下:
example/
example/
dashapp/
static/
custom-css.css
templates/
base.html
home.html
login.html
__init__.py
app1.py
forms.py
models.py
routes.py
application.py
config.py
users.db
我的Dash应用位于app1.py
中。我尝试了几种方法来通过current_user
,但没有成功。不过,它在home.html
中表现良好。我猜问题出在我的应用程序位于单独的文件中,而不是routes.py
中。
这是app.py
的代码:
import dash
import dash_html_components as html
from dashapp import application
from flask_login import login_required, current_user
app1 = dash.Dash(__name__, server = application, routes_pathname_prefix = '/app1/', assets_folder = 'static', assets_url_path = '/static')
app1.scripts.config.serve_locally = True
app1.css.config.serve_locally = True
app1.layout = html.Div(
children = '{}'.format(current_user)
)
for view_func in app1.server.view_functions:
if view_func.startswith('/app1/'):
app1.server.view_functions[view_func] = login_required(app1.server.view_functions[view_func])
routes.py
代码:
from flask import render_template, flash, redirect, url_for, request
from flask_login import login_user, logout_user, current_user, login_required
from werkzeug.urls import url_parse
from dashapp import application, db
from dashapp.forms import LoginForm
from dashapp.models import User
from dashapp import app1
@application.route('/')
@application.route('/home')
@login_required
def home():
return render_template('home.html')
@application.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('home')
return redirect(next_page)
return render_template('login.html', form=form)
@application.route('/app1/')
@application.route('/logout')
def logout():
logout_user()
return redirect(url_for('login'))
其他脚本几乎是标准的,除非确实需要,否则我不会在问题中包含它们。
请提出如何克服我的问题的建议。谢谢!
答案 0 :(得分:0)
我设法在一些帮助下解决了这个问题。万一有人卡住,请参阅下面的更新代码。
添加了session
行以将当前用户名存储在routes.py
中:
from flask import render_template, flash, redirect, url_for, request, session
from flask_login import login_user, logout_user, current_user, login_required
from werkzeug.urls import url_parse
from dashapp import application, db
from dashapp.forms import LoginForm
from dashapp.models import User
from dashapp import app1
@application.route('/')
@application.route('/home')
@login_required
def home():
return render_template('home.html')
@application.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
session['username'] = current_user.username
return redirect(url_for('home'))
form = LoginForm()
if form.validate_on_submit():
session['username'] = form.username.data
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('home')
return redirect(next_page)
return render_template('login.html', form=form)
@application.route('/logout')
def logout():
session.pop('username', None)
logout_user()
return redirect(url_for('login'))
在session
的回调中还有app1.py
:
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
from dashapp import application
from flask_login import login_required
from flask import session
app1 = dash.Dash(__name__, server = application, routes_pathname_prefix = '/app1/', assets_folder = 'static', assets_url_path = '/static')
app1.scripts.config.serve_locally = True
app1.css.config.serve_locally = True
app1.layout = html.Div(
children = [
html.Div(id='div2'),
html.Div(id='div3', children = 'xxxx'),
],
)
@app1.callback(
Output('div2', 'children'),
[Input('div3', 'children')])
def update_intervalCurrentTime(children):
return session.get('username', None)
for view_func in app1.server.view_functions:
if view_func.startswith('/app1/'):
app1.server.view_functions[view_func] = login_required(app1.server.view_functions[view_func])
答案 1 :(得分:0)
遇到同样的问题。我想问题是当“应用程序”注册Dash应用程序时,当前用户尚未初始化。不错的解决方法,尽管由于Flask会话只是经过编码而显得有些不安全。
https://github.com/RafaelMiquelino/dash-flask-login/blob/master/app.py-我认为是更强大的解决方案。它检查回调中的current_user并将页面内容用作Input,因此在页面加载时调用回调。如果用户体验不成问题,您还可以跳过视图的保护。
这是我的用法的简化示例:
@app.callback(
Output('graph-wrapper', 'children'),
[Input('page-content', 'children')])
def load_graph(input1):
if current_user.is_authenticated:
return dcc.Graph() # Dash Graph populated with current_user data from db
else:
return ''