WTForms:同一页面上的两个表单?

本文介绍了WTForms:同一页面上的两个表单?的处理方法,对大家解决问题具有一定的参考价值

问题描述

我有一个动态网页,它应该处理两种表单:登录表单注册表单.我正在使用 WTForms 来处理这两个表单,但我在使其工作时遇到了一些麻烦,因为这两个表单都被渲染到同一页面.

I have a dynamic web-page that should process two forms: a login form and a register form. I am using WTForms to process the two forms but I am having some trouble making it work, since both forms are being rendered to the same page.

以下是我的网页登录表单的代码:

The following is the code for the login form of my webpage:

PYTHON:
class Login(Form):
    login_user = TextField('Username', [validators.Required()])
    login_pass = PasswordField('Password', [validators.Required()])

@application.route('/index', methods=('GET', 'POST'))
def index():
    l_form = Login(request.form, prefix="login-form")
    if request.method == 'POST' and l_form.validate():
        check_login = cursor.execute("SELECT * FROM users WHERE username = '%s' AND pwd = '%s'"
        % (l_form.login_user.data, hashlib.sha1(l_form.login_pass.data).hexdigest()))
        if check_login == True:
            conn.commit()
            return redirect(url_for('me'))
    return render_template('index.html', lform=l_form)


HTML:
<form name="lform" method="post" action="/index">
    {{ lform.login_user }}
    {{ lform.login_pass }}
    <input type="submit" value="Login" />
</form>

以下是我的网页注册表单的代码:

The following is the code for the register form of my webpage:

PYTHON:
class Register(Form):
    username = TextField('Username', [validators.Length(min=1, max = 12)])
    password = PasswordField('Password', [
        validators.Required(),
        validators.EqualTo('confirm_password', message='Passwords do not match')
    ])
    confirm_password = PasswordField('Confirm Password')
    email = TextField('Email', [validators.Length(min=6, max=35)])

@application.route('/index', methods=('GET','POST'))
def register():
    r_form = Register(request.form, prefix="register-form")
    if request.method == 'POST' and r_form.validate():
        check_reg = cursor.execute("SELECT * FROM users WHERE username = '%s' OR `e-mail` = '%s'"
        % (r_form.username.data, r_form.email.data))

        if check_reg == False:
            cursor.execute("INSERT into users (username, pwd, `e-mail`) VALUES ('%s','%s','%s')"
            % (r_form.username.data, hashlib.sha1(r_form.password.data).hexdigest(), check_email(r_form.email.data)))
            conn.commit()
            return redirect(url_for('index'))
    return render_template('index.html', rform=r_form)


HTML:
<form name="rform" method="post" action="/index">
    {{ rform.username }}
    {{ rform.email }}
    {{ rform.password }}
    {{ rform.confirm_password }}
    <input type="submit" value="Register />
</form>

当我继续加载网页时出现以下错误:

I get the following error when I go ahead and load the webpage:

    Traceback (most recent call last):
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflaskapp.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:UsersHTVal_000DesktopinnoCMSmain.py", line 36, in index
    return render_template('index.html', lform=l_form)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflask	emplating.py", line 128, in render_template
    context, ctx.app)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesflask	emplating.py", line 110, in _render
    rv = template.render(context)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesjinja2environment.py", line 969, in render
    return self.environment.handle_exception(exc_info, True)
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesjinja2environment.py", line 742, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:UsersHTVal_000DesktopinnoCMS	emplatesdefaultindex.html", line 52, in top-level template code
    {{ rform.username }}
  File "C:UsersHTVal_000DesktopinnoCMSvirtualenvlibsite-packagesjinja2environment.py", line 397, in getattr
    return getattr(obj, attribute)
UndefinedError: 'rform' is undefined

据我所知,表格之间存在冲突,因为根据回溯:

From what I understand, there is a conflict between the forms because according to the traceback:

return render_template('index.html', lform=l_form)

返回以下错误:

UndefinedError: 'rform' is undefined

当脚本看到:

{{ rform.username }}
{{ rform.email }}
{{ rform.password }}
{{ rform.confirm_password }}

但它完全忽略了:

{{ lform.login_user }}
{{ lform.login_pass }}

可能有点混乱,我也很困惑,我希望有人以前遇到过这个问题,这样我也可以解决它.

It might be a little confusing, I am confused loads as well, and I hope that someone has faced this problem before so that I could solve it too.

推荐答案

这有点混乱,因为你在 index() 和 register() 上渲染 index.html,并且都注册了相同的路由 (@application.route('/index')).当您将表单提交到 /index 时,只会调用其中之一.你可以

This is a bit confusing, because you render index.html on both index() and register(), and both register the same route (@application.route('/index')). When you submit your form to /index, only one of them only ever get called. You can either

  • 将所有逻辑放在一个索引函数中,看看哪种形式(如果有)是有效的.
  • 分离你的逻辑,只提交相关的表单

通常,您希望将逻辑分开,即使您希望在同一页面上同时显示登录和注册.所以我会尝试向你展示正确的方向:-)

Generally, you want to separate the logic, even if you want to show both the login and signup on the same page. So I'll try to show you in the right direction :-)

例如,首先将您的登录视图和注册视图分开,现在只会检查与它们相关的表单的逻辑:

For example, first separate your login and register views, which will now only check the logic for the form that concerns them:

class Login(Form):
    login_user = TextField('Username', [validators.Required()])
    login_pass = PasswordField('Password', [validators.Required()])

class Register(Form):
    username = TextField('Username', [validators.Length(min=1, max = 12)])
    password = PasswordField('Password', [
        validators.Required(),
        validators.EqualTo('confirm_password', message='Passwords do not match')
    ])
    confirm_password = PasswordField('Confirm Password')
    email = TextField('Email', [validators.Length(min=6, max=35)])

@application.route('/login', methods=['POST'])
def index():
    l_form = Login(request.form, prefix="login-form")
    if l_form.validate():
        check_login = cursor.execute("SELECT * FROM users WHERE username = '%s' AND pwd = '%s'"
            % (l_form.login_user.data, hashlib.sha1(l_form.login_pass.data).hexdigest()))
        if check_login == True:
            conn.commit()
            return redirect(url_for('me'))
    return render_template('index.html', lform=l_form, rform=Register())

@application.route('/register', methods=['POST'])
def register():
    r_form = Register(request.form, prefix="register-form")
    if r_form.validate():
        check_reg = cursor.execute("SELECT * FROM users WHERE username = '%s' OR `e-mail` = '%s'"
            % (r_form.username.data, r_form.email.data))

        if check_reg == False:
            cursor.execute("INSERT into users (username, pwd, `e-mail`) VALUES ('%s','%s','%s')"
                % (r_form.username.data, hashlib.sha1(r_form.password.data).hexdigest(), check_email(r_form.email.data)))
            conn.commit()
            return redirect(url_for('index'))
    return render_template('index.html', lform=Login(), rform=r_form)

@application.route('/index')
def index():
    # If user is logged in, show useful information here, otherwise show login and register
    return render_template('index.html', lform=Login(), rform=Register())

然后,创建一个显示两个表单的 index.html 并将它们发送到正确的方向.

Then, create a index.html that shows both forms and send them in the right direction.

<form name="lform" method="post" action="{{ url_for('login') }}">
    {{ lform.login_user }}
    {{ lform.login_pass }}
    <input type="submit" value="Login" />
</form>

<form name="rform" method="post" action="{{ url_for('register') }}">
    {{ rform.username }}
    {{ rform.email }}
    {{ rform.password }}
    {{ rform.confirm_password }}
    <input type="submit" value="Register" />
</form>

该代码未经测试,因此可能存在错误,但我希望它能够为您指明正确的方向.请注意,我们在对 render('index.html', ...) 的所有调用中都传递了 lform 和 rform.

The code is untested, so there might be bugs, but I hope it sends you in the right direction. Notice that we pass both lform and rform in all calls to render('index.html', ...).

更简单的改进/重构方法:使用函数检查现有用户(您的 SELECT 语句)并使用 Jinja2 的包含或宏来处理模板中的各个表单.

Further easy ways to improve/refactor: use a function to check for an existing user (your SELECT statement) and use Jinja2's includes or macros for the individual forms in the templates.

这篇关于WTForms:同一页面上的两个表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

admin_action_{$_REQUEST[‘action’]}

do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

日期:2020-09-02 17:44:16 浏览:1127

admin_footer-{$GLOBALS[‘hook_suffix’]}

do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

日期:2020-09-02 17:44:20 浏览:1032

customize_save_{$this->id_data[‘base’]}

do_action( "customize_save_{$this-&gt;id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

日期:2020-08-15 15:47:24 浏览:775

customize_value_{$this->id_data[‘base’]}

apply_filters( "customize_value_{$this-&gt;id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

日期:2020-08-15 15:47:24 浏览:866

get_comment_author_url

过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

日期:2020-08-10 23:06:14 浏览:903

network_admin_edit_{$_GET[‘action’]}

do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

日期:2020-08-02 09:56:09 浏览:848

network_sites_updated_message_{$_GET[‘updated’]}

apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

日期:2020-08-02 09:56:03 浏览:834

pre_wp_is_site_initialized

过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

日期:2020-07-29 10:15:38 浏览:809

WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

日期:2020-10-03 21:18:25 浏览:1620

谷歌的SEO是什么

SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

日期:2020-10-30 17:23:57 浏览:1263