WTForms:在同一页上的两种形式? [英] WTForms: two forms on the same page?

查看:130
本文介绍了WTForms:在同一页上的两种形式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个动态的网页,可以处理两种形式:登录表单注册表单。我正在使用WTForms来处理这两个表单,但是我有一些麻烦使它工作,因为这两个表单都呈现在同一页面。



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

  PYTHON:
类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()
返回重定向(url_for('me'))
return render_template('index.html',lform = l_form)


HTML:
< form name =lformmethod =postaction =/ index> ;
{{lform.login_user}}
{{lform.login_pass}}
< input type =submitvalue =Login/>
< / form>

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

  PYTHON:
class Register(Form):
username = TextField('Username',[validators。长度(min = 1,max = 12)])
密码= PasswordField('Password',[
validators.Required(),
validators.EqualTo('confirm_password',message =密码不匹配')
))
confirm_password = PasswordField('确认密码')
email = TextField('Email',[validators.Length(min = 6,max = 35) ])
$ b $ application_route('/ index',methods =('GET','POST'))
def register():
r_form = Register如果request.method =='POST'和r_form.validate():
check_reg = cursor.execute(SELECT * FROM users WHERE username =' %s'或'e-mail` ='%s'
%(r_form.username.data,r_form.email.data))

如果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)

$ b HTML:
< form name =rform method =postaction =/ index>
{{rform.username}}
{{rform.email}}
{{rform.password}}
{{rform.confirm_password}}
< input type =submitvalue =Register />
< / form>

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

  Traceback(最近一次调用最后一次):
文件C:\ Users \ HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py,行1836,在__call__
返回自我。 wsgi_app(ENVIRON,start_response)
档 C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py,线路1820,在wsgi_app
response = self.make_response(self.handle_exception(e))
文件C:\ Users \HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages \flask\app.py,第1403行,在handle_exception
reraise(exc_type,ex c_value,tb)
在wsgi_app文件C:\ Users \HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py,1817行
response = self.full_dispatch_request()
文件C:\ Users \HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py ,第1477行,在full_dispatch_request
rv = self.handle_user_exception(e)
文件C:\ Users \HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages \flask\app.py,第1381行,在handle_user_exception
reraise(exc_type,exc_value,tb)
文件C:\ Users\HTVal_000\Desktop\innoCMS\virtualenv \lib\site-packages\flask\app.py,行1475,在full_dispatch_request
rv = self.dispatch_request()
文件C:\ Users \HTVal_000\ Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py ,第1461行,在dispatch_request
返回self.view_functions [rule.endpoint](** req.view_args)
文件C:\ Users \ HKTV_000\Desktop\innoCMS\main。 py,第36行,在索引
返回render_template('index.html',lform = l_form)
文件C:\ Users'HTVal_000 \Desktop\innoCMS\virtualenv\ lib \site-packages\flask\templating.py,第128行,在render_template
context,ctx.app)
文件C:\ Users\HTVal_000\Desktop\ innoCMS\virtualenv\lib\site-packages\flask\templating.py,第110行,在_render
rv = template.render(context)
文件C:\ Users \HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\jinja2\environment.py,行969,在渲染
返回self.environment.handle_exception(exc_info,True)
文件C:\ Users \HTVal_000\Desktop\innoCMS\virtualenv\lib\网站packages\jinja2\environment.py 电线742,在handle_exception
再加注(exc_type,exc_value,TB)
档 C:\Users\HTVal_000\Desktop\innoCMS \templates\default\index.html,第52行,在顶层模板代码
{{rform.username}}
文件C:\ Users \HTVal_000\Desktop \innoCMS\virtualenv\lib\site-packages\jinja2\environment.py,第397行,在getattr
返回getattr(obj,属性)
UndefinedError:'rform'is undefined

据我所知,表单之间有冲突,因为根据traceback: p>

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

返回以下错误:

  UndefinedError:'rform'未定义

当脚本看到时:

  {{rform.username} } 
{{rform.email}}
{{rform.password}}
{{rform.confirm_password}}
$ b $ pre $ {{lform.login_user}} $

b $ b {{lform.login_pass}}

可能有点混乱,也希望有人遇到这个问题,以便我也能解决。

解决方案

这有点令人困惑,因为您在index()和register()相同的路由( @ application.route('/ index'))。当你将表单提交给 / index 时,只有其中一个被调用。您可以将

$ ul

  • 放在一个索引函数中,看看哪个表单(如果有的话)是有效的。

  • 分开你的逻辑,只提交相关的表单



  • 一般来说,即使你想要分开逻辑在同一页面上显示登录和注册。所以我会试着向你展示正确的方向: - )

    例如,首先分开你的登录和注册视图,现在只会检查逻辑表单:

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

    注册(表单):
    username = TextField ,[validators.Length(min = 1,max = 12)])
    password = PasswordField('Password',[
    validators.Required(),
    validators.EqualTo('confirm_password' ,message ='密码不匹配')
    ])
    confirm_password = PasswordField('确认密码')
    email = TextField('Email',[validators.Length(min = 6, ())
    $ b $ application_route('/ login',methods = ['POST'])
    def index():
    l_form = Login .form,prefix =登录表单)
    如果l_form.validate():
    check_login = cursor.execute( SELECT * FROM用户其中username = '%s' 和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'))
    返回render_template('index.html',lform = l_form,rform = Register())

    @ application.route('/ register',methods = ['POST'])$ b $ ():
    r_form = Register(request.form,prefix =register-form)
    如果r_form.validate():
    check_reg = cursor.execute(SELECT * FROM用户WHERE username ='%s'或'e-mail` ='%s'
    %(r_form.username.data,r_form.email.data))

    check_reg ==假:
    cursor.execute(插入到用户(用户名,密码,电子邮件)VALUES('%s','%s','%s')
    % (r_form.username.data,hashlib.sha 1(r_form.password.data).hexdigest(),check_email(r_form.email.data)))
    conn.commit()
    返回重定向(url_for( '索引'))
    返回render_template('index.html',lform = Login(),rform = r_form)

    @ application.route('/ index')
    def index():
    #如果用户登录,在这里显示有用的信息,否则显示登录和注册
    返回render_template('index.html',lform = Login(),rform = Register())

    $ b
    $ b $ b

     < form name =lformmethod =postaction ={{url_for('login')}}> 
    {{lform.login_user}}
    {{lform.login_pass}}
    < input type =submitvalue =Login/>
    < / form>

    < form name =rformmethod =postaction ={{url_for('register')}}>
    {{rform.username}}
    {{rform.email}}
    {{rform.password}}
    {{rform.confirm_password}}
    < input type =submitvalue =Register/>
    < / form>

    代码没有经过测试,所以可能会有错误,但是我希望它能够向正确的方向发送。请注意,我们在所有调用中都传递了lform和rform来渲染('index.html',...)。

    改进/重构的更简单方法:使用函数来检查一个已经存在的用户(你的 SELECT 语句),并使用Jinja2的包含或宏作为模板中的各个表单。


    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:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1836, in __call__
        return self.wsgi_app(environ, start_response)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1820, in wsgi_app
        response = self.make_response(self.handle_exception(e))
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1403, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1817, in wsgi_app
        response = self.full_dispatch_request()
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
        rv = self.dispatch_request()
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\app.py", line 1461, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "C:\Users\HTVal_000\Desktop\innoCMS\main.py", line 36, in index
        return render_template('index.html', lform=l_form)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\templating.py", line 128, in render_template
        context, ctx.app)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\flask\templating.py", line 110, in _render
        rv = template.render(context)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\jinja2\environment.py", line 969, in render
        return self.environment.handle_exception(exc_info, True)
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\jinja2\environment.py", line 742, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "C:\Users\HTVal_000\Desktop\innoCMS\templates\default\index.html", line 52, in top-level template code
        {{ rform.username }}
      File "C:\Users\HTVal_000\Desktop\innoCMS\virtualenv\lib\site-packages\jinja2\environment.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)
    

    Returns the following error:

    UndefinedError: 'rform' is undefined
    

    When the script sees:

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

    But it completely ignores:

    {{ 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.

    解决方案

    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

    • put all your logic in one index function and see which form (if any) is valid.
    • seperate your logic and only submit the relevant form

    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())
    

    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>
    

    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', ...).

    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:在同一页上的两种形式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆