Prakhar Agrawal
Prakhar Agrawal

Reputation: 1022

Web2Py handle auth form at backend

The database model structure is as shown below.

I want to present user with a registration form that asks for hostel_name and then at the backend convert the hostel_name to store it according hostel 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}}

The above present code presents user with a registration form and expects user to enter the hostel id. What do I need to change to enable this?

Any help is appreciated.

Upvotes: 1

Views: 280

Answers (1)

Anthony
Anthony

Reputation: 25536

You can explicitly define an IS_IN_DB validator for the hostel_id field, providing a label argument to specify labels to be used in the HTML select widget:

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

The IS_IN_DB validator will cause SQLFORM to generate a select widget for the field, and its label argument will result in the hostel_name field being used to generate labels for the widget, even though the actual db.hostels.id values will be inserted in the database.

The represent attribute specifies how values will be shown in read-only forms and in the grid.

Note, all of the above (both the requires and represent attributes) can be achieved more simply be just specifying the format argument when defining the db.hostels 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')

With the above format argument, any tables that reference db.hostels will automatically get the IS_IN_DB validator and represent attribute as shown above.

Finally, if you intend to use the web2py Auth system, rather than creating your own users table, you should simply extend or re-define the standard db.auth_user table. This is explained here. Also, for security purposes, you should not store passwords as plain text -- so you should use the CRYPT validator with the password field (the standard db.auth_user table does this automatically).

Upvotes: 1

Related Questions