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 到文章页面时如何检索它。

我尝试过的:

我很好奇在数据库中存储(分配值、db.commit() 等)是否是正确的路径,或者我是否应该更多地探索烧瓶会话。我需要此信息在会话中保持不变,以便在用户注销、清除 cookie、使用不同的设备等时它仍然可用。我以后可能还会对这些值进行分析。

谢谢

我会选择重定向解决方案,它更清晰。

我会在 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 属性),这也会起作用。我还没有彻底检查这个案例,因为在我的用例中,用户必须登录才能查看内容。