Web2Py 在后端处理身份验证表单

Web2Py handle auth form at backend

数据库模型结构如下图所示。

我想向用户提供一个注册表单,要求输入 hostel_name,然后在后端转换 hostel_name 以根据旅馆 ID 存储它。

controller/default.py

def user():
    return dict(form=auth())

models/db.py

db.define_table(
    'hostels',
    Field('hostel_admin_group_id', 'integer'),
    Field('hostel_residents_group_id', 'integer'),
    Field('hostel_name', length=32, unique=True),
 )


db.define_table(
    'users',
    Field('username', length=32, unique=True),
    Field('password', 'password', length=32, readable=False, label='Password'),
    Field('first_name', 'string', length=32, default=''),
    Field('last_name', 'string', length=32, default=''),
    Field('email_id', 'string', length=32),
    Field('degree_name', 'string', length=32),
    Field('hostel_id', db.hostels),
    Field('picture_id', 'integer'),
    Field('year_of_degree', 'integer'),
 )

views/user.html

{{extend 'layout.html'}}

<h2>
{{=T('Sign Up') if request.args(0) == 'register' else T('Log In') if request.args(0) == 'login' else T(request.args(0).replace('_',' ').title())}}
</h2>

<div class="container">
    <div class="row">
        <div id="web2py_user_form" class="col-lg-6">
        {{
        if request.args(0)=='login':
            if not 'register' in auth.settings.actions_disabled:
                form.add_button(T('Sign Up'),URL(args='register', vars={'_next': request.vars._next} if request.vars._next else None),_class='btn btn-default')
            pass
            if not 'request_reset_password' in auth.settings.actions_disabled:
                form.add_button(T('Lost Password'),URL(args='request_reset_password'),_class='btn btn-default')
            pass
        pass
        =form
        }}
        </div>
    </div>
</div>


{{block page_js}}
<script>
    jQuery("#web2py_user_form input:visible:enabled:first").focus();
{{if request.args(0)=='register':}}
    web2py_validate_entropy(jQuery('#auth_user_password'),100);
{{elif request.args(0)=='change_password':}}
    web2py_validate_entropy(jQuery('#no_table_new_password'),100);
{{pass}}
</script>
{{end page_js}}

上面的代码向用户展示了一个注册表单,并希望用户输入旅馆 ID。我需要更改什么才能启用此功能?

感谢任何帮助。

您可以为 hostel_id 字段显式定义一个 IS_IN_DB 验证器,提供一个 label 参数来指定要在 HTML [=47= 中使用的标签] 小部件:

    Field('hostel_id', db.hostels,
          requires=IS_IN_DB(db, 'hostels.id', label='%(hostel_name)s'),
          represent=lambda ref, row: ref.hostel_name)

IS_IN_DB 验证器将导致 SQLFORM 为该字段生成一个 select 小部件,其 label 参数将导致 hostel_name 字段用于为小部件生成标签,即使实际 db.hostels.id 值将被插入到数据库中。

represent 属性指定值如何以只读形式和在网格中显示。

注意,以上所有(requiresrepresent 属性)都可以更简单地实现,只需在定义 db.hostels 时指定 format 参数table:

db.define_table(
    'hostels',
    Field('hostel_admin_group_id', 'integer'),
    Field('hostel_residents_group_id', 'integer'),
    Field('hostel_name', length=32, unique=True),
    format='%(hostel_name)s')

使用上述 format 参数,任何引用 db.hostels 的 table 将自动获得 IS_IN_DB 验证器和 represent 属性,如上所示。

最后,如果您打算使用 web2py 身份验证系统,而不是创建您自己的 users table,您应该简单地扩展或重新定义标准 db.auth_user table。这是解释 here。此外,为了安全起见,您不应将密码存储为纯文本——因此您应该在密码字段中使用 CRYPT 验证器(标准 db.auth_user table 会自动执行此操作)。