in model or controller?

79 views
Skip to first unread message

Alex Glaros

unread,
Apr 15, 2015, 1:50:34 PM4/15/15
to web...@googlegroups.com
Here is a regular requires is_in_db statement:


gov_org_query = (db.Organization.organizationPrimaryTypeID ==1)

db.GovOrgJurisdiction.organizationID.requires = IS_IN_DB(db(gov_org_query), 'Organization.id', '%(organizationFullName)s',zero=T('choose one'))


is it more efficient to put these two in the controller so they are called only when used?

I don't understand if they would get executed needlessly if placed in the model if the function that needs them is not used for many sessions

thanks

Alex Glaros

Lisandro

unread,
Apr 15, 2015, 2:37:09 PM4/15/15
to web...@googlegroups.com
I think you won't notice any difference in the performance. 
If you care about that query, you don't have to worry, because the query will only be executed when the field needs to be rendered (in a form), or in the moment of the validation (when submitting the form). 

So I would say that you leave those lines in the model. For mantainance and debugging purposes, it will be more practical to keep all database definition and restrictions in the model/s file/s. 
The only reason I can imagine to put that requires in the controller is if you have different requires in different controller/functions for the same db field.

Hope that helps.

Niphlod

unread,
Apr 15, 2015, 2:37:22 PM4/15/15
to web...@googlegroups.com
putting

db.tablename.fieldname.requires = VALIDATOR()

doesn't do anything BUT if you have lazy_tables turned on, this syntax would trigger the "unlazyification" of the table.
"Minus points" (the reverse concept of "bonus points") for

db.tablename.fieldname.requires = IS_IN_DB(db.othertable)

syntax that will trigger the "unlazyification" of both tables.

For all intents and purposes, a fixed validator that needs to be there in every piece of code interacting with that field is better placed in the table definition itself, i.e.

db.define_table('tablename', Field('fieldname', requires=VALIDATOR()))

in this way, when you enable lazy_tables the "unlazyification" would only be triggered at the first access of db.tablename throughout your code.

Then again, if for some strict requirement you aren't able to define a validator "inside" the table definition, again for the solely purposes of lazy_tables, you should use the on_define argument

All of this is explained in the book at chapter 6 (the "on_define" is here)

Alex Glaros

unread,
Apr 15, 2015, 3:26:06 PM4/15/15
to web...@googlegroups.com
Thanks guys,

Alex

--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/-GAJKa-1yHI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alex Glaros

unread,
Apr 15, 2015, 6:05:23 PM4/15/15
to web...@googlegroups.com
regarding validator "better placed in the table definition itself"

what about the "represents" and "readable/writable" statements?  Is there efficiency in moving those to the table definition?

Alex


Richard Vézina

unread,
Apr 15, 2015, 6:07:41 PM4/15/15
to web2py-users
@Simone,

Is that true unlazy... if the .requires = Something is place in controller file??

I mean, models/files are parsed before controller and if ".requires = something" is in controller the model should be unlazy anyway...

Richard

--
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.

Rod Watkins

unread,
Apr 15, 2015, 6:18:47 PM4/15/15
to web...@googlegroups.com
I have this question as well. And, also, what bout custom widgets assigned after the table definition? Does that trigger the unlazification as well?
TIA

Niphlod

unread,
Apr 15, 2015, 6:26:36 PM4/15/15
to web...@googlegroups.com
in order:

@alex: same thing. if you can stuff everything inside the define_table() call you'll be sure to have everything working in the speediest way with lazy_tables.

@richard: if you put a requires in the controller, the second that line is executed, the table is unlazyed. The whole point of the thread should obviously "fenced" into the scenario what can I do to speedup model execution, since the controller function is executed anyway.

@rod: same thing.

<tl;dr> for everybody: tables stay lazy until someone does db.tablename. Pythonicly-speaking, the getattr(tablename) on "db" triggers the unlazyification.

<tl;dr> for evertbody, part two. the toolbar (response.toolbar()) has a nice section that lists lazy and non-lazy tables. Checking if your models are "in order" just takes three simple steps:
- create a fresh controller, i.e. controllers/testlazy.py
- create a test function in that controller, i.e.
def does_nothing():
    return dict()
- hit appname/testlazy/does_nothing: by default the generic view shows the toolbar. If you have all the tables listed as lazy you did a goo job. If not, inspect your app to find any db.tablename call.

Rod Watkins

unread,
Apr 15, 2015, 6:55:51 PM4/15/15
to web...@googlegroups.com
Thanks Niphlod. That was very useful, especially the toolbar trick. I was not aware of that. Many thanks!
Rod

Annet

unread,
Apr 16, 2015, 4:13:54 AM4/16/15
to web...@googlegroups.com
Hi Niphlod,


- hit appname/testlazy/does_nothing: by default the generic view shows the toolbar. If you have all the tables listed as lazy you did a goo job. If not, inspect your app to find any db.tablename call.

All but two of my tables are listed as lazy: auth_user and nd_node

I defined a custom auth_user table


## custom auth_user table
db.define_table(
    auth.settings.table_user_name,
    Field('first_name'),
    Field('last_name'),
    Field('email', length=128, default='', requires=[IS_EMAIL(), IS_NOT_IN_DB(db, 'auth_user.email')], notnull=True, unique=True'),
    Field('username', length=32, default='', requires=[ IS_NOT_EMPTY(), IS_NOT_IN_DB(db, 'auth_user.username')], notnull=True, unique=True, writable=False, readable=False),
    Field('password', type='password', length=512, requires=[IS_STRONG(),CRYPT()], writable=False, readable=False),
    Field('nodeID', 'reference nd_node', requires=[IS_EMPTY_OR(IS_IN_DB(db, 'nd_node.id', '%(id)s'))], ondelete='CASCADE', writable=False, readable=False),
    Field('registration_key', length=512, default='', writable=False, readable=False),
    Field('reset_password_key', length=512, default='', writable=False, readable=False),
    Field('registration_id', length=512, default='', writable=False, readable=False),
    Field('createdOn', **attributes),
    Field('modifiedOn', update=request.now, **attributes))

## get the custom_auth_table
custom_auth_table = db[auth.settings.table_user_name]
## tell auth to use custom_auth_table
auth.settings.table_user = custom_auth_table
## create all tables needed by auth if not custom tables
auth.define_tables(migrate=False, username=True, signature=False)


What's wrong with this definition?


Kind regards,

Annet

Niphlod

unread,
Apr 16, 2015, 5:51:53 AM4/16/15
to web...@googlegroups.com
custom_auth_table = db[auth.settings.table_user_name]
Reply all
Reply to author
Forward
0 new messages