"Runtime Error: working outside of application context" when trying to instantiate WTForms object in Flask view

2.4k views Asked by At

So i have a form defined like this:

class NewDashForm(Form):
    tabname = StringField('tabname', validators=[DataRequired(),Length(1,16)])
    title = StringField('title', validators=[DataRequired(),Length(1,128)])

And I am importing it in my views.py file, but when I try to instantiate it like this:

form = NewDashForm()

I get the "working outside of application context" error. The application is generated by a "factory" method, like this:

def generate_application(config=None):
   application = Flask(__name__)
   application.config.from_object(config)
   application.register_blueprint(cheda.generate_blueprint(application.config,application.db))
   return application

There is some db related stuff that I left out in this last code snippet, but you get the idea. From my understanding, anything that happens from within a view should automatically be under application context, but clearly I am missing something. What am I doing wrong here?

Traceback (most recent call last):
  File "/vagrant/venv/cheda_env/bin/cheda-run", line 9, in <module>
    load_entry_point('cheda==0.1.0', 'console_scripts', 'cheda-run')()
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/pkg_resources/__init__.py", line 546, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/pkg_resources/__init__.py", line 2666, in load_entry_point
    return ep.load()
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/pkg_resources/__init__.py", line 2339, in load
    return self.resolve()
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/pkg_resources/__init__.py", line 2345, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/code/cheda/cheda/cmd/run.py", line 10, in <module>
    from .. import application
  File "/code/cheda/cheda/application.py", line 16, in <module>
    from .blueprints import cheda
  File "/code/cheda/cheda/blueprints/cheda.py", line 10, in <module>
    from ..views import views as cheda_views
  File "/code/cheda/cheda/views/views.py", line 37, in <module>
    class NewDash(JsonApiView):
  File "/code/cheda/cheda/views/views.py", line 39, in NewDash
    form = NewDashForm()
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/wtforms/form.py", line 212, in __call__
    return type.__call__(cls, *args, **kwargs)
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/flask_wtf/form.py", line 68, in __init__
    csrf_enabled = current_app.config.get('WTF_CSRF_ENABLED', True)
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/werkzeug/local.py", line 338, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/werkzeug/local.py", line 297, in _get_current_object
    return self.__local()
  File "/vagrant/venv/cheda_env/lib/python3.4/site-packages/flask/globals.py", line 34, in _find_app
    raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context
1

There are 1 answers

0
davidism On BEST ANSWER

You should only instantiate forms within view fuctions, doing so outside a request doesn't make sense. You are getting the error because it's trying to get data from the request, which isn't present.

If you really need to instantiate it before hand, either pass empty data to it so it doesn't look at the request, or use a request context.

from werkzeug.datastructrues import MultiDict
form = MyForm(MultiDict())

# or

with app.test_request_context():
    form = MyForm()

Again, you should never be doing this in your application, a form is only useful inside a view during a request. The test request context would be useful if you wanted to test the form in a unit test.