Flask:何时使用会话与将用户数据存储在数据库中?
Flask: when to use session vs. storing user data in db?
我有一个 Flask 应用程序,需要在用户浏览内容时存储用户的位置。
比如我有这样一条路线:@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
内容的组织方式使您可以分页浏览某个类别下的文章:从 0 开始,然后是 1,依此类推。第 3 篇文章的 URL 看起来像:articles/<category>/3
我想保存用户的位置,这样如果他们在访问文章 3 后离开网站,当他们导航到文章页面时,他们将登陆 articles/<category>/3
,而不是 articles/<category>/0
.
实现此目标的最佳方法是什么?目前,我已经对数据库中的数据进行了建模,因此有一列看起来像 category_article_last_visited
(整数)。我可以在用户浏览网站时存储这些数据,但我不确定当他们 return 到文章页面时如何检索它。
我尝试过的:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new', 'article_number':current_user.category_article_last_visited})
,但我得到一个错误,没有这样的属性。
- 在路线功能中检查
current_user.category_article_last_visited
并使用商品编号。这会呈现正确的内容,但不会更改 URL,这是行不通的。
- 重定向具有
current_user.category_article_last_visited
值的用户。这似乎没有产生任何变化。
我很好奇在数据库中存储(分配值、db.commit() 等)是否是正确的路径,或者我是否应该更多地探索烧瓶会话。我需要此信息在会话中保持不变,以便在用户注销、清除 cookie、使用不同的设备等时它仍然可用。我以后可能还会对这些值进行分析。
- 我上面描述的方法是最好的方法吗? flask-sessions 还是其他更可取?
- 如果上面列出的方法是最好的,我如何正确路由此信息,以便将用户定向到他们离开的页面,并适当更改 URL?
谢谢
我会选择重定向解决方案,它更清晰。
我会在 route-function 的开头添加一个 if 语句,如果有这个用户的数据,我会重定向到那个页面。例如:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
def routefunc():
if current_user.category_article_last_visited !=0: #or whatever your column keeps for empty data
return redirect ('/articles/'+yourcategory +'/'+ current_user.category_article_last_visited #as string
这必须与其他一些功能结合使用,以避免不定式重定向到此路由:
选项 1:
您可以在路由中添加另一个变量,该变量将对这些重定向具有特定值,并将忽略此 if 语句。例如:
@main_bp.route('/articles/<category>/<article_number>/<check>', defaults={'category': 'new'})
def routefunc():
if current_user.category_article_last_visited !=0 and check!=1: return redirect ('/articles/'+yourcategory +'/'+ current_user.category_article_last_visited+'/1')
但是在这种情况下,您必须将此变量(具有不同于 1 的其他值)添加到所有 urls-hrefs 等,这会使您的网址更“脏”。它对小型应用程序有效,但我会避免使用具有多个内部链接的大型 app/website。
选项 2:
您可以在数据库中再添加一列 table,这将是 1/0,具体取决于用户何时直接或通过重定向访问此路由。在这种情况下,您必须添加几个查询来检查 and/or 更新此值 before-after 重定向。
选项 3:
您可以创建另一个只处理重定向的类似路由,并产生相同的结果(相同 html)但没有 if 语句。例如:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
def routefunc():
if current_user.category_article_last_visited !=0: #or whatever your column keeps for empty data
return redirect ('/articles2/'+yourcategory +'/'+ current_user.category_article_last_visited #as string
@main_bp.route2('/articles2/<category>/<article_number>', defaults={'category': 'new'})
def routefunc():
return ('yourhtml.html')
***基于会话的方法在这里并不适用,因为您需要一个长期解决方案。
由于您可能有很多类别、文章、用户,您最好单独创建一个 table 专门为此
我不知道什么是最好的方法来实现你想要的,但你可以尝试以下方法。假设您想对数据执行一些分析,您可能希望将其存储在数据库中。
当新用户访问您的页面并将他重定向到带有新 cookie 集的文章页面时,您可以设计一个路由来创建用户 cookie:
@main_bp.route('/articles/set_cookie', "GET"])
def set_article_cookie():
sessionserializer = securecookiesessioninterface().get_signing_serializer(main_bp)
tempcookie = sessionserializer.dumps(dict(session))
resp = make_response(redirect('/articles'))
resp.set_cookie("user", tempcookie)
return resp
以及您检查用户是否已经访问该页面的现有路线。在这种情况下,您需要在数据库中检查他阅读的最后一篇文章是什么,并相应地重定向他:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
def articles(category, article_number):
# If the user cookie is already set, check if there is some data is the database and redirect to his last article visited
cookie = request.cookies
if "user" in cookie:
# Retreive the user cookie value and check the database for this value
return redirect('/articles/' + last_article_visited)
# Else redirect the user to set_article_cookie
else:
return redirect("/set_article_cookie")
好的,这是我决定的解决方案:
- 我更新了整个网站的导航链接路径,所以
/articles/<category>/0
是 /articles/<category>/current_user.article_number_last_visited
- 由于不是所有用户都访问过每个分类的文章,我添加了默认路由逻辑,类似:
@main_bp.route('/articles/<category>/', defaults={'article_number': 0})
@main_bp.route('/articles/<category>/<article_number>', methods=['GET', 'POST'])
即使 current_user.article_number 为空,这也会正确地路由用户。
我相信如果用户未登录(因此不会有 article_number
属性),这也会起作用。我还没有彻底检查这个案例,因为在我的用例中,用户必须登录才能查看内容。
我有一个 Flask 应用程序,需要在用户浏览内容时存储用户的位置。
比如我有这样一条路线:@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
内容的组织方式使您可以分页浏览某个类别下的文章:从 0 开始,然后是 1,依此类推。第 3 篇文章的 URL 看起来像:articles/<category>/3
我想保存用户的位置,这样如果他们在访问文章 3 后离开网站,当他们导航到文章页面时,他们将登陆 articles/<category>/3
,而不是 articles/<category>/0
.
实现此目标的最佳方法是什么?目前,我已经对数据库中的数据进行了建模,因此有一列看起来像 category_article_last_visited
(整数)。我可以在用户浏览网站时存储这些数据,但我不确定当他们 return 到文章页面时如何检索它。
我尝试过的:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new', 'article_number':current_user.category_article_last_visited})
,但我得到一个错误,没有这样的属性。- 在路线功能中检查
current_user.category_article_last_visited
并使用商品编号。这会呈现正确的内容,但不会更改 URL,这是行不通的。 - 重定向具有
current_user.category_article_last_visited
值的用户。这似乎没有产生任何变化。
我很好奇在数据库中存储(分配值、db.commit() 等)是否是正确的路径,或者我是否应该更多地探索烧瓶会话。我需要此信息在会话中保持不变,以便在用户注销、清除 cookie、使用不同的设备等时它仍然可用。我以后可能还会对这些值进行分析。
- 我上面描述的方法是最好的方法吗? flask-sessions 还是其他更可取?
- 如果上面列出的方法是最好的,我如何正确路由此信息,以便将用户定向到他们离开的页面,并适当更改 URL?
谢谢
我会选择重定向解决方案,它更清晰。
我会在 route-function 的开头添加一个 if 语句,如果有这个用户的数据,我会重定向到那个页面。例如:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
def routefunc():
if current_user.category_article_last_visited !=0: #or whatever your column keeps for empty data
return redirect ('/articles/'+yourcategory +'/'+ current_user.category_article_last_visited #as string
这必须与其他一些功能结合使用,以避免不定式重定向到此路由:
选项 1:
您可以在路由中添加另一个变量,该变量将对这些重定向具有特定值,并将忽略此 if 语句。例如:
@main_bp.route('/articles/<category>/<article_number>/<check>', defaults={'category': 'new'})
def routefunc():
if current_user.category_article_last_visited !=0 and check!=1: return redirect ('/articles/'+yourcategory +'/'+ current_user.category_article_last_visited+'/1')
但是在这种情况下,您必须将此变量(具有不同于 1 的其他值)添加到所有 urls-hrefs 等,这会使您的网址更“脏”。它对小型应用程序有效,但我会避免使用具有多个内部链接的大型 app/website。
选项 2:
您可以在数据库中再添加一列 table,这将是 1/0,具体取决于用户何时直接或通过重定向访问此路由。在这种情况下,您必须添加几个查询来检查 and/or 更新此值 before-after 重定向。
选项 3:
您可以创建另一个只处理重定向的类似路由,并产生相同的结果(相同 html)但没有 if 语句。例如:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
def routefunc():
if current_user.category_article_last_visited !=0: #or whatever your column keeps for empty data
return redirect ('/articles2/'+yourcategory +'/'+ current_user.category_article_last_visited #as string
@main_bp.route2('/articles2/<category>/<article_number>', defaults={'category': 'new'})
def routefunc():
return ('yourhtml.html')
***基于会话的方法在这里并不适用,因为您需要一个长期解决方案。 由于您可能有很多类别、文章、用户,您最好单独创建一个 table 专门为此
我不知道什么是最好的方法来实现你想要的,但你可以尝试以下方法。假设您想对数据执行一些分析,您可能希望将其存储在数据库中。
当新用户访问您的页面并将他重定向到带有新 cookie 集的文章页面时,您可以设计一个路由来创建用户 cookie:
@main_bp.route('/articles/set_cookie', "GET"])
def set_article_cookie():
sessionserializer = securecookiesessioninterface().get_signing_serializer(main_bp)
tempcookie = sessionserializer.dumps(dict(session))
resp = make_response(redirect('/articles'))
resp.set_cookie("user", tempcookie)
return resp
以及您检查用户是否已经访问该页面的现有路线。在这种情况下,您需要在数据库中检查他阅读的最后一篇文章是什么,并相应地重定向他:
@main_bp.route('/articles/<category>/<article_number>', defaults={'category': 'new'})
def articles(category, article_number):
# If the user cookie is already set, check if there is some data is the database and redirect to his last article visited
cookie = request.cookies
if "user" in cookie:
# Retreive the user cookie value and check the database for this value
return redirect('/articles/' + last_article_visited)
# Else redirect the user to set_article_cookie
else:
return redirect("/set_article_cookie")
好的,这是我决定的解决方案:
- 我更新了整个网站的导航链接路径,所以
/articles/<category>/0
是/articles/<category>/current_user.article_number_last_visited
- 由于不是所有用户都访问过每个分类的文章,我添加了默认路由逻辑,类似:
@main_bp.route('/articles/<category>/', defaults={'article_number': 0})
@main_bp.route('/articles/<category>/<article_number>', methods=['GET', 'POST'])
即使 current_user.article_number 为空,这也会正确地路由用户。
我相信如果用户未登录(因此不会有 article_number
属性),这也会起作用。我还没有彻底检查这个案例,因为在我的用例中,用户必须登录才能查看内容。