如何将值存储为特定于用户的全局变量?

时间:2018-10-18 17:13:31

标签: python flask sqlalchemy

我目前正在开发一个小型烧瓶应用程序,该应用程序将连接到api并处理从该api提取的数据。

用户可以登录到我的flask应用程序,然后还可以定义其凭据以与api进行交互。任何给定的用户都可以具有与其用户相关联的一个或多个API凭据。

我已经创建了数据库模型,将用户和Api凭据存储在数据库中,如下所示。

我正在使用flask-login模块,该模块具有“ current_user ”对象,该对象为我提供了当前在整个应用程序中登录的用户的用户模型。

型号:

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(128), index=True, unique=True)
    firstname = db.Column(db.String(55))
    lastname = db.Column(db.String(55))
    password = db.Column(db.String(128))
    creds = db.relationship('ApiCredential', backref='owner', lazy='dynamic')

class ApiCredential(db.Model):
    __tablename__ = 'api_credentials'
    id = db.Column(db.Integer, primary_key=True)
    site = db.Column(db.String(140))
    user = db.Column(db.String(140))
    username = db.Column(db.String(100), index=True, unique=True)
    password = db.Column(db.String(55))
    base = db.Column(db.String(100))
    owner_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    active = db.Column(db.Boolean)

我想知道如何为我的API凭证创建类似的“全局变量”,该凭证仅特定于登录用户而不是应用程序的所有用户

注意***似乎“ current_user”是一个称为本地代理的东西,我一点都不熟悉,而且似乎找不到任何合适的文档或说明它是什么以及如何满足我的需要

2 个答案:

答案 0 :(得分:1)

您将乐在其中,最后您可能会选择做一些不太魔术的事情。

首先,它有助于了解current_user的工作方式。来源(目前为止)是here。这是一个werkzeug.local.LocalProxy,其中包含一个调用flask_login.utils._get_user的lambda。

LocalProxy非常酷,理解它是在Python上进行升级的好方法,但是flask-login使用的只是其中的一小部分。来源(目前为止)是here。它看起来很吓人,但是如果您跟踪代码,它只会调用本地arg(flask-login中的lambda)。

这使我们回到_get_user(到目前为止,here),如果没有用户(在当前请求上下文的顶部),它将加载用户,然后返回用户从请求上下文的顶部开始。

您可以遵循这种模式,并编写一个导出current_credentials的程序包。您将遵循相同的模式,使用werkzeug.local.LocalProxy来包装调用了_get_credentials的lambda。诀窍是从current_user中导入flask-login,并将其与_get_credentials结合使用,以获取用于构造查询以连接到ApiCredentials表的用户。

或者您可以采用一种简单的方法,并编写实用程序方法供您的视图使用,该方法将使用current_user来获取用户,然后进行联接以获取该用户的API凭据。

答案 1 :(得分:0)

一种方法可能是在烧瓶应用程序中创建新路由,当用户get请求该页面时,您可以检查它是哪个用户,一旦知道了哪个用户,就可以使用您的查询api凭证模型并通过current_user.id进行过滤。

creds = ApiCredentials.query.filter_by(owner_id=current_user.id).first_or_404()

然后,您可以根据需要使用API​​凭据表中存储的信息进行操作。

我不明白您为什么要复制用户加载器功能。这是您在设置Flask登录时将要包含的功能。很短的函数,它从用户模型返回当前用户对象。

您可以显示或返回您的api密钥。将它们以HTML形式显示在页面上,或者用于更多自治工作,您可以使用jsonify将键作为json字符串返回。

很抱歉,这并不能直接回答您的问题,但是希望我的建议可以使您得到一个稍微复杂一些的答案,并且您可以继续开发Web应用程序。也许值得稍后再访。

注意:这不在我的头上。我提供的代码行可能需要如下所示

creds = ApiCredentials.query.filter_by(owner_id==current_user.id).first()

此外,如果表中存储了多个api凭据,则可能不希望使用.first()

在这种情况下,这将更合适:

creds = ApiCredentials.query.filter_by(owner_id==current_user.id).all()