Шаблон рендеринга дает jinja2.exceptions.UndefinedError: «форма» не определена

Я работаю над Mega Tutorial Miguel Grinberg Flask, и я не могу понять, почему индексная страница теперь не загружается. Вот трассировка:

  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask_login.py", line 658, in decorated_view
    return func(*args, **kwargs)
  File "/home/asdoylejr/microblog/app/views.py", line 44, in index
    posts = posts)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/templating.py", line 128, in render_template
    context, ctx.app)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/flask/templating.py", line 110, in _render
    rv = template.render(context)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/jinja2/environment.py", line 969, in render
    return self.environment.handle_exception(exc_info, True)
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/jinja2/environment.py", line 742, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/asdoylejr/microblog/app/templates/index.html", line 2, in top-level template code
    {% extends "base.html" %}
  File "/home/asdoylejr/microblog/app/templates/base.html", line 30, in top-level template code
    {% block content %}{% endblock %}
  File "/home/asdoylejr/microblog/app/templates/index.html", line 7, in block "content"
    {{form.hidden_tag()}}
  File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/jinja2/environment.py", line 397, in getattr
    return getattr(obj, attribute)
UndefinedError: 'form' is undefined

Вот код рассматриваемой индексной страницы:

<!-- extend base layout -->
{% extends "base.html" %}

{% block content %}
<h1>Hi, {{g.user.nickname}}!</h1>
<form action="" method="post" name="post">
    {{form.hidden_tag()}}
<table>
    <tr>
        <td>Say something:</td>
        <td>{{form.post(size = 30, maxlength = 140)}}</td>
        <td>
        {% for error in form.errors.post %}
        <span style="color: red;">[{{error}}]</span><br>
        {% endfor %}
        </td>
    </tr>
    <tr>
        <td></td>
        <td><input type="submit" value="Post!"></td>
        <td></td>
    </tr>
</table>
</form>
{% for post in posts %}
<p>
    {{post.author.nickname}} says: <b>{{post.body}}</b>
</p>
{% endfor %}
{% endblock %}

И вот код в представлении:

@app.route('/', methods = ['GET', 'POST'])
@app.route('/index', methods = ['GET', 'POST'])
@login_required
def index():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(body = form.post.data, timestamp = datetime.utcnow(), author = g.user)
        db.session.add(post)
        db.session.commit()
        flash('Your post is now live!')
        return redirect(url_for('index'))
    posts = g.user.followed_posts().all()
    return render_template("index.html",
        title = 'Home',
        user = user,
        posts = posts)

Я прочел учебник несколько раз и сравнивал свой код с исходным кодом в конце каждого урока, и я понятия не имею, почему он не работает. Я не уверен, почему у него возникают проблемы с передачей формы в этом представлении, когда оно не возвращает формы ошибки при передаче в другом представлении.

Может кто-то указать мне верное направление?


person asdoylejr    schedule 21.10.2013    source источник


Ответы (3)


Сообщение об ошибке, которое вы получили, объясняется в трассировке стека. В частности, здесь:

File "/home/asdoylejr/microblog/app/templates/index.html", line 7, in block "content"
{{form.hidden_tag()}}

File "/home/asdoylejr/microblog/flask/lib/python2.7/site-packages/jinja2/environment.py", line 397, in getattr
return getattr(obj, attribute)

UndefinedError: 'form' is undefined

Сообщение об ошибке исходит от Jinja, в котором говорится, что form не определено. Ваш шаблон пытается использовать form...

...
{% block content %}
<h1>Hi, {{g.user.nickname}}!</h1>
<form action="" method="post" name="post">
    {{form.hidden_tag()}}
<table>
    ...

... но вы никогда не передавали его как часть своего метода render_template (вы определили только title, user и posts)...

return render_template("index.html",
        title = 'Home',
        user = user,
        posts = posts)
person Mark Hildreth    schedule 21.10.2013

Вы должны передать form в качестве переменной контекста. Попробуй это:

@app.route('/', methods = ['GET', 'POST'])
@app.route('/index', methods = ['GET', 'POST'])
@login_required
def index():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(body = form.post.data, timestamp = datetime.utcnow(), author = g.user)
        db.session.add(post)
        db.session.commit()
        flash('Your post is now live!')
        return redirect(url_for('index'))
    posts = g.user.followed_posts().all()
    return render_template("index.html",
        title = 'Home',
        user = user,
        posts = posts,
        form = form)
person zero323    schedule 21.10.2013

Вы не передали форму в своем шаблоне.

Потому что это часть вашего HTML-шаблона.

return render_template("index.html",
        title = 'Home',
        user = user,
        posts = posts,
        form = form) # <<<-------------------- Here.
person Rohit Dalal    schedule 11.01.2020