2

我收到了这个错误,我想要任何形式的输入,因为它现在是一堵砖墙。

我有一个使用flask-security 的应用程序,它通过flask-login 导入current_user。任何集成问题都已成为过去,并且已经存在了一段时间。

我需要过滤对某些特定信息的请求,我将其放在 g 上。我有一个可行的蓝图,任何集成问题都已成为过去。

昨天我把这个请求过滤蓝图函数提取到一个通用的扩展中,基本上把info过滤到g,配置变得更容易了,所以或多或少已经准备好测试了。此扩展替换此蓝图以制作跨应用程序请求过滤器

我把它放回我的应用程序,现在我才得到它,并且如上所述它是不透明的:我不知道用户在哪里或为什么不在 RequestContext

Traceback (most recent call last):
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/flask/app.py", line 1356, in full_dispatch_request
    rv = self.preprocess_request()
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/flask/app.py", line 1539, in preprocess_request
    rv = func()
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/Flask_Flarf-0.0.1-py2.7.egg/flask_flarf/flarf.py", line 48, in preprocess_request
    preprocess_func(r)
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/Project_Producer-0.0.1-py2.7.egg/project_producer/config/configs/request_filters_config.py", line 10, in preprocess_with_user
    g.preprocessed = current_app.extensions['flarf'].preprocess_cls(request)
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/Project_Producer-0.0.1-py2.7.egg/project_producer/config/configs/request_filters_config.py", line 17, in __init__
    self.aid = self.determine_account(request)
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/Project_Producer-0.0.1-py2.7.egg/project_producer/config/configs/request_filters_config.py", line 51, in determine_account
    current_user.account.identifier])
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/werkzeug/local.py", line 336, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/werkzeug/local.py", line 295, in _get_current_object
    return self.__local()
  File "/home/zv/.virtualenvs/j/lib/python2.7/site-packages/flask_login.py", line 403, in <lambda>
    current_user = LocalProxy(lambda: _request_ctx_stack.top.user)
AttributeError: 'RequestContext' object has no attribute 'user'

理论:

1)这个功能:

def preprocess_request(preprocess_func=self.preprocess_func):
        r = _request_ctx_stack.top.request
        request_endpoint = str(r.url_rule.endpoint).rsplit('.')[-1]
        if request_endpoint not in _flarf.preprocess_skip:
            preprocess_func(r)

所以上面在跟踪中发生的事情是 preprocess_request 运行调用了一个应用程序本地定义的 preprocess_func,它本身创建了一个应用程序本地定义的类实例以附加到 g,这个本地定义的类实例使用'current_user'......这就是它错误。

在使用 _request_ctx_stack 尚未与用户联系或删除用户的情况下四处奔走,之前或其他事情。多次弹出或触摸 _request_ctx_stack.top.request 可能“不好”

2) 操作顺序,preprocess_request 在 flask-security 添加用户之前运行

3)没有线索,有点丢失atm

有什么建议么?

编辑:

问题很可能是方法解析,因为 current_app.before_request_funcs 返回:

{None: [<function flarf_filter_request at 0x1a781b8>, <bound method LoginManager._load_user of <flask_login.LoginManager object at 0x1a79990>>, <bound method Principal._on_before_request of <flask_principal.Principal object at 0x1a80290>>]}

所以主要的收获是我做错了,如果我需要获取 before_request 信息,那么在烧瓶运行这些函数的 before_request 时间内获取该信息并不是最佳的,因为目前没有 before_request 函数的排序。

选项?

  1. 添加一个选项以将 before_request 函数排序到烧瓶中,可能就像优先关键字和调用 sorted 或有序 dict 一样简单

  2. 用我正在做的事情改变策略,例如将它从 before_request 更改为装饰器。但是,这将需要按视图表示法,创建蓝图和扩展的全部目的是跳过必须在每个视图的基础上收集某些信息。好处将是计划中的多个过滤器。

  3. 一个有用的预制解决方案:Flask-Classy


4

1 回答 1

1

嘿,我也遇到了这个问题,但是使用 Django,完全相同的错误。所以我认为这可能是相似的。RequestContext 不是请求,但它包含它。它是 django 中的一个特殊类,当它由您的视图创建时,它实际上包含请求以及您从视图传递到模板的所有其他上下文变量。

以下是它的创建方式:

c = RequestContext(request, {
    'foo': 'bar',
})

更多关于这里。在Flask文档中。

长话短说,RequestContext 是一个字典,其中包含“请求”键中的请求。所以你可以这样访问它:

request = context['request']
user = request.user

在您的模板中,您可以像往常一样访问 request , request.user 应该可以工作。希望这会有所帮助,我觉得这在 Flask 和 Django 中可能是相似的。如果这没有帮助,您可以打印出您的上下文并查看其中包含哪些数据。这就是我发现我的问题的方式。

干杯

于 2014-10-09T16:12:19.773 回答