使用bootstrap_flask 的render_form渲染表单时,报错jinja2.exceptions.UndefinedError: 'sayhello.views.HelloForm object' has no attribute 'html'

各位好,
我在参照Flask Web开发实战,写sayhello这个程序的时候,遇到了无法渲染表单的错误,完整报错如下:

    Traceback (most recent call last):
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "D:\sayhello\venv\Lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py",line1821,in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "D:\sayhello\venv\Lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "D:\sayhello\venv\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "D:\sayhello\sayhello\views.py", line 27, in index
    return render_template('index.html',form=form,messages=messages)
  File "D:\sayhello\venv\Lib\site-packages\flask\templating.py", line 137, in render_template
    return _render(
  File "D:\sayhello\venv\Lib\site-packages\flask\templating.py", line 120, in _render
    rv = template.render(context)
  File "D:\sayhello\venv\Lib\site-packages\jinja2\environment.py", line 1090, in render
    self.environment.handle_exception()
  File "D:\sayhello\venv\Lib\site-packages\jinja2\environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "D:\sayhello\venv\Lib\site-packages\jinja2\_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "D:\sayhello\sayhello\templates\index.html", line 2, in top-level template code
    {%from bootstrap/form.html import render_form%}
jinja2.exceptions.UndefinedError: 'sayhello.views.HelloForm object' has no attribute 'html'

我最开始完全按照书上的组织方式去组织代码结构,发现该报错后,为了排除其它可能原因,我将class HelloForm的定义直接移入views.py中,还删除了HelloForm类中的所有内容,用pass代替。
但依然出现该报错。我尝试debug进入报错部分代码,然而能力有限,未能解决该问题。
views.py和构造文件以及index.html的完整代码如下:
views.py:

from sayhello import app
from flask import render_template,flash,redirect,url_for
from flask_wtf import FlaskForm
from wtforms import StringField,TextAreaField,SubmitField
from wtforms.validators import DataRequired,Length

class HelloForm(FlaskForm):
    name=StringField('昵称',validators=[DataRequired(),Length(1,20)])
    body=TextAreaField('内容',validators=[DataRequired(),Length(1,200)])
    submit=SubmitField()

@app.route('/',methods=['GET','POST'])
def index():
    form=HelloForm()
    if form.validate_on_submit():
        flash('你的消息发给了全世界!')
        return redirect(url_for('index'))
    return render_template('index.html',form=form)

init.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from flask_moment import Moment

app=Flask('sayhello')
app.config.from_pyfile('settings.py')
app.jinja_env.trim_blocks=True
app.jinja_env.lstrip_blocks=True
bootstrap=Bootstrap(app)
moment=Moment(app)
db=SQLAlchemy(app)

from sayhello import views,errors,commands

index.html

{% extends 'base.html' %}
{%from bootstrap/form.html import render_form%}
{% block content %}

    {{render_form(form,action=request.full_path)}}

{% endblock %}

(PS:这个markdown直接把html标签都识别为显示内容了,我只发了index.html中的部分内容,不过已经足够看了。)

另外,附上我所使用所有包的版本:

Bootstrap-Flask==1.2.0
click==8.0.3
colorama==0.4.4
Faker==4.0.2
Flask==1.1.2
Flask-Moment==0.9.0
Flask-SQLAlchemy==2.4.1
Flask-WTF==0.14.3
greenlet==1.1.2
itsdangerous==2.0.1
Jinja2==2.11.1
MarkupSafe==2.0.1
pathtools==0.1.2
PyMySQL==1.0.2
python-dateutil==2.8.1
python-dotenv==0.12.0
six==1.14.0
SQLAlchemy==1.3.15
text-unidecode==1.3
watchdog==0.10.2
Werkzeug==2.0.3
WTForms==2.2.1

运行程序使用的是flask run的方式

猜测是这一行的语法有问题,语法标记和代码之间用空格隔开试试?

{% from bootstrap/form.html import render_form %}

哈哈哈,我跟阿灰老师想到一块去了,我改过这个地方啦,

但是报错信息没有变化

代码有没有放到 GitHub?我可以下载下来运行试试看。之前没遇到过这个报错……

GitHub - HAVELIGHT/sayhello

OK,我等下运行试试看。

找到问题了,之前竟然没注意到……那个导入路径要加引号:

{% from 'bootstrap/form.html' import render_form %}

遇到问题可以多和书里或 GitHub 上的代码对比对比。

额… 尴尬了。抱歉耽误您时间了。

1 Like