zoukankan      html  css  js  c++  java
  • flask RuntimeError: Working outside of application context 问题解决

    前言

    最近学习flask表单的时候,碰到了一个问题,看着教程百思不得其解,所以查阅了一些资料的终于把这个困扰了我两个晚上的问题解决了。

    问题详情

    在教程中的是这样写的:

    (venv) D:VScodehelloflask>flask shell
    Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32
    App: app [production]
    Instance: D:VScodehelloflaskinstance
    >>> from flask_wtf import FlaskForm
    >>> from wtforms import StringField,PasswordField, BooleanField,SubmitField
    >>> from wtforms.validators import DataRequired,Length
    >>>
    >>> class LoginForms(FlaskForm):
    ...     username = StringField('Username', validators=[DataRequired()])
    ...     password = PasswordField('Password', validators=[DataRequired(),Length(8,128)])
    ...     remember = BooleanField('Remember me')
    ...     submit = SubmitField('Log in')
    ... 
    >>> login = LoginForms()

    但是这样写之后,却发现报错了:

    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "d:vscodehelloflaskvenvlibsite-packageswtformsform.py", line 208, in __call__ 
        return type.__call__(cls, *args, **kwargs)
      File "d:vscodehelloflaskvenvlibsite-packagesflask_wtfform.py", line 87, in __init__
        super(FlaskForm, self).__init__(formdata=formdata, **kwargs)
      File "d:vscodehelloflaskvenvlibsite-packageswtformsform.py", line 274, in __init__ 
        self.process(formdata, obj, data=data, **kwargs)
      File "d:vscodehelloflaskvenvlibsite-packageswtformsform.py", line 131, in process
        field.process(formdata)
      File "d:vscodehelloflaskvenvlibsite-packageswtformscsrfcore.py", line 43, in process
        self.current_token = self.csrf_impl.generate_csrf_token(self)
      File "d:vscodehelloflaskvenvlibsite-packagesflask_wtfcsrf.py", line 141, in generate_csrf_token
        token_key=self.meta.csrf_field_name
      File "d:vscodehelloflaskvenvlibsite-packagesflask_wtfcsrf.py", line 45, in generate_csrf
        if field_name not in session:
      File "d:vscodehelloflaskvenvlibsite-packageswerkzeuglocal.py", line 379, in <lambda>
        __contains__ = lambda x, i: i in x._get_current_object()
      File "d:vscodehelloflaskvenvlibsite-packageswerkzeuglocal.py", line 306, in _get_current_object
        return self.__local()
      File "d:vscodehelloflaskvenvlibsite-packagesflaskglobals.py", line 38, in _lookup_req_object
        raise RuntimeError(_request_ctx_err_msg)
    RuntimeError: Working outside of request context.
    
    This typically means that you attempted to use functionality that needed
    an active HTTP request.  Consult the documentation on testing for
    information about how to avoid this problem.

    作为小白的我看的是一脸懵逼啊。完全不知道出了什么问题。翻译了一下大致的意思就是你需要一个活动的HTTP请求,可是我该怎么办呢。

    然后我又尝试了一种办法,把上面这个问题我们记为问题1

    (venv) D:VScodehelloflask>ipython
    Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)]
    Type 'copyright', 'credits' or 'license' for more information
    IPython 7.18.1 -- An enhanced Interactive Python. Type '?' for help.
    
    In [1]: from flask_wtf import FlaskForm
       ...: from wtforms import StringField,PasswordField, BooleanField,SubmitField
       ...: from wtforms.validators import DataRequired,Length
       ...: 
       ...: class LoginForms(FlaskForm):
       ...:     username = StringField('Username', validators=[DataRequired()])
       ...:     password = PasswordField('Password', validators=[DataRequired(),Length(8,128)])
       ...:     remember = BooleanField('Remember me')
       ...:     submit = SubmitField('Log in')
       ...: 
    
    In [2]: forms = LoginForms()

    但是又报错了。

    RuntimeError: Working outside of application context.
    
    This typically means that you attempted to use functionality that needed
    to interface with the current application object in some way. To solve
    this, set up an application context with app.app_context().  See the
    documentation for more information.

    意思就是没有在应用的上下文中。到这里我已经不知道怎么办了。。欲哭无泪,但是我们还是把这个问题记为问题2吧,总归是要解决的

    解决问题

    但是我没有放弃尝试和查找资料该如何解决,经过我2天下班后的不断折腾,终于在一个论坛中看见了一个和我一样的问题。

    并且看到了其中一个回复:

    看到后觉得如获至宝,就立马去flask shell中尝试了一下:

    (venv) D:VScodehelloflask>flask shell
    Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32
    App: app [production]
    Instance: D:VScodehelloflaskinstance
    >>> from flask_wtf import FlaskForm
    >>> from wtforms import StringField,PasswordField, BooleanField,SubmitField
    >>> from wtforms.validators import DataRequired,Length
    >>>
    >>> class LoginForms(FlaskForm):
    ...     username = StringField('Username', validators=[DataRequired()])
    ...     password = PasswordField('Password', validators=[DataRequired(),Length(8,128)])
    ...     remember = BooleanField('Remember me')
    ...     submit = SubmitField('Log in')
    ... 
    >>> with app.test_request_context():
    ...     form = LoginForms()
    ... 
    >>> form.username()
    Markup('<input id="username" name="username" required type="text" value="">')
    >>>

    多谢这位大佬的指点,那么问题1到这里就算是解决了。但是问题2还没有解决,为此我决定去看看这个上下文的东西。

    终于解决了困扰了2天的问题:

    (venv) D:VScodehelloflask>ipython
    Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)]
    Type 'copyright', 'credits' or 'license' for more information
    IPython 7.18.1 -- An enhanced Interactive Python. Type '?' for help.
    
    In [1]: from app import app
    
    In [2]: from flask import current_app
    
    In [3]: app_ctx = app.app_context()
    
    In [4]: app_ctx.push()
    
    In [5]: from flask_wtf import FlaskForm
       ...: from wtforms import StringField,PasswordField, BooleanField,SubmitField
       ...: from wtforms.validators import DataRequired,Length
       ...: 
       ...: class LoginForms(FlaskForm):
       ...:     username = StringField('Username', validators=[DataRequired()])
       ...:     password = PasswordField('Password', validators=[DataRequired(),Length(8,128)])
       ...:     remember = BooleanField('Remember me')
       ...:     submit = SubmitField('Log in')
       ...: 
    
    In [6]: with app.test_request_context():
       ...:     form = LoginForms()
       ...: 
    
    In [7]: form.username()
    Out[8]: Markup('<input id="username" name="username" required type="text" value="">')
    
    In [9]: 

    问题总结

    问题1

    首先在问题1中我们使用了flask shell的方式进入shell,根据教程中的解释,在使用flask shell的时候自动会进入应用上下文情境。但是我们创建forms表单,没有使用的app.test_request_context():进入请求的上下文情境,所以导致运行报错没有活动的HTTP请求。因为初始化就没有在请求的情境中。

    问题2

    第二次我没有使用flask shell的方式进入shell,然后运行报错set up an application context with app.app_context(),因为我进入的是python的shell并没有进入flask的shell,所以报错了。然后我们根据查的资料的手动推送一下应用的上下文情境,然后在进行请求的情境,这样我们的代码执行就没有错误了。至于为什么不用 with app.app_context() ,因为在with语句外面,我们这个情境已经被释放了。所以运行就会继续报第二个问题的错误了。除非我们全部在with语句中的进行操作,但是这是不太现实的,所以需要手动的去调节。

    后记

    经过这么一番的折腾,总结学东西还是要多查资料,多坚持一会,也许今天困扰你的东西,明天就豁然开朗了。

  • 相关阅读:
    Python 2.7 中使用 Print 方法
    python
    Python 中 global、nonlocal的使用
    PYTHON中 赋值运算的若干问题总结
    Python List 中 Append 和 Extent 方法不返回值。
    由Python的一个小例子想到的
    PHP环境安全加固
    Tomcat服务安全加固
    网站被植入Webshell的解决方案
    Apache服务安全加固
  • 原文地址:https://www.cnblogs.com/wxhou/p/13765033.html
Copyright © 2011-2022 走看看