[web2py] Re: put function on models or modules

2017-03-28 Thread 黄祥
got it, thank you so much for explaination, anthony

thanks and best regards,
stifan

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-28 Thread Anthony

>
> Field("from_date", "date", 
>  requires = test_field_constructor.requires_date) )
>

Note, you have not created the requires_date function so that it acts as a 
validator -- rather, when called, it merely returns an instance of a 
validator. So, you must actually call it above:

requires=test_field_constructor.requires_date()

Anthony

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-28 Thread 黄祥
clear enough for callback function, thank you so much for detail 
explaination, anthony, better to move it to modules, it didnt appear in 
snakeviz result when it's not called
for current i understand the reason, but when i move it to lambda or 
function without arguments, it return an error.
*e.g.*
*modules/test_field_constructor.py*
#requires_date = lambda: IS_DATE(format = current.T('%Y-%m-%d'), 
error_message = current.T('Enter date as -mm-dd') )
def requires_date(): 
return IS_DATE(format = current.T('%Y-%m-%d'), error_message = 
current.T('Enter date as -mm-dd') )

*controllers/default.py*
def test_form():
redirect_url = 'test'
form = SQLFORM.factory(
Field("from_date", "date", 
 requires = test_field_constructor.requires_date) )
if form.process().accepted:
from_date = form.vars.from_date

response.new_window = URL(redirect_url, args = from_date)
elif form.errors:
response.flash = T('Form has errors')
return dict(form = form)

*error traceback :*
raise Exception(msg)
Exception: Validation error, field:from_date  at 
0x10e9d6c80>

any idea how to use lambda or function without arguments in web2py modules?

thanks and best regards,
stifan

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-27 Thread Anthony
On Monday, March 27, 2017 at 12:39:43 AM UTC-4, 黄祥 wrote:
>
> a, i c, my assumption is whatever showed in snakeviz result, is all the 
> python files that executed, btw, there still odd for me, why login_onfail 
> callback function is not showed snakeviz, wheter it's executed or defined?
>

Just to clarify, the output "db_schema_1_person.py:3()" does not 
indicate that a function has been called (note, "" rather than a 
function name). I think that line just indicates that the module/file was 
loaded, and line #3 is the first line with any code (it just coincidentally 
happens to be the line where before_insert_person is defined). login_onfail 
is not defined at the top of a file, so its line number does not appear 
anywhere in the output.
 

> *modules/test_field_constructor.py*
> requires_marital_status = IS_IN_SET([('Single', current.T('Single') ), 
> ('Married', current.T('Married') ), 
> ('Divorced', current.T('Divorced') ) ], 
> zero = current.T('Choose One') )
>

You still shouldn't do that, as the current.T object is local to a specific 
thread. Always use attributes of current within functions/methods inside 
the module.

Anthony

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-26 Thread 黄祥
a, i c, my assumption is whatever showed in snakeviz result, is all the 
python files that executed, btw, there still odd for me, why login_onfail 
callback function is not showed snakeviz, wheter it's executed or defined?

*an error traceback for IS_IN_DB() is :*
requires_person = IS_IN_DB(current.db, current.db.person.id, 
current.db.person._format)
AttributeError: 'thread._local' object has no attribute 'db'

fixed by put it on function, at first i just define it as is
requires_person = IS_IN_DB(current.db, current.db.person.id, 
current.db.person._format) # error
because another requires is not error when defined as is:
*e.g.*
*modules/test_field_constructor.py*
requires_marital_status = IS_IN_SET([('Single', current.T('Single') ), 
('Married', current.T('Married') ), 
('Divorced', current.T('Divorced') ) ], 
zero = current.T('Choose One') )

# not error
def requires_person(has_membership_admin, auth_user_person):
return IS_IN_DB(current.db if has_membership_admin else 
current.db(current.db.person.id == auth_user_person.id), 
current.db.person.id, current.db.person._format)

thx anthony for detail explaination

best regards,
stifan

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-26 Thread Anthony

>
> *db_schema_1_person.py:3()*
>

Line 3 is the line where the before_insert_person function is *defined, *not 
where it is *called*. The output does not indicate the function has 
actually been called.
 

> *another question is about validator*
> e.g.
> requires_person = IS_IN_DB(db, db.person.id, db.person._format)
>
> the above code works when put in models and controllers, why i can't put 
> it on modules, it's return an error, is there any way to put it on modules 
> using web2py way?
> *modules/test_field_constructor.py*
> requires_person = IS_IN_DB(current.db, current.db.person.id, 
> current.db.person._format)* # return an error*
>

First, in a model file, have you actually set the value of current.db? 
Second, is that line of code at the top level of the module, or within a 
function or method (only the latter will work properly)? What is the error?

Anthony

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-26 Thread 黄祥
ok, i tried to minimalized the scope (start from simple scratch)
*1. copy welcome scaffolding app*
cp -R ~/site/web2py/applications/welcome/ ~/site/web2py/applications/z
*2. Run Web2py with profiler*
source ~/site/bin/activate
python ~/site/web2py/web2py.py --nogui --no-banner -a 'a' -i 0.0.0.0 -p 
8000 -F ~/Downloads/profiler
*3. modified models/db.py (put in the bottom the code in example 1 above)*
def login_onfail(form):
username = request.vars.username
row = db((db.auth_user.username == username ) ).iterselect(cache = 
cache_db, 
   cacheable = 
True).first()
if row is not None:
db.auth_event.insert(time_stamp = request.now, 
 client_ip = request.client, 
 user_id = id, 
 origin = '%s/%s' % (request.controller, 
request.function), 
 description = '%s login failed' % (username) )

auth.settings.login_onfail.append(login_onfail)
*4. create new file models/db_schema_1_person.py (to eliminate another code 
i make a new file that contain code in example 2 above)*
# -*- coding: utf-8 -*-

def before_insert_person(f):
if f['auth_user']:
query_auth_user = (db.auth_user.id == f['auth_user'] )
row_auth_user = db(query_auth_user).iterselect(cache = (cache.ram, 
3600), 
   cacheable = 
True).first()
f['username'] = row_auth_user.username
f['first_name'] = row_auth_user.first_name
f['last_name'] = row_auth_user.last_name
f['email'] = row_auth_user.email

def on_define_person(table): 
table._before_insert.append(before_insert_person)

db.define_table('person', 
Field('is_auth', 'boolean'),
Field('auth_user', 'reference auth_user'), 
Field('username'), 
Field('first_name'), 
Field('last_name'), 
Field('email', 'list:string'), 
on_define = on_define_person, 
format = lambda r: '%s %s' % (r.first_name, r.last_name) )
*5. Remove profiled files from previous to make easiest to see the current 
one running*
rm -rf ~/Downloads/profiler/*
*6. Go to new web2py app using browser : http://127.0.0.1:8000/z*
*7. Run snakeviz*
source ~/site/bin/activate
snakeviz ~/Downloads/profiler/req_uuid.prof
*8. Snakeviz result in models side :*
*filename:lineno(funtion)*
*db.py:8()*
*db_schema_1_person.py:13(on_define_person)*
*db_schema_1_person.py:3()*

explain db.py:8 is about, (the default scaffolding app)
if request.global_settings.web2py_version < "2.14.1":
raise HTTP(500, "Requires web2py 2.13.3 or newer")

db_schema_1_person.py:13(on_define_person), no question in here either

db_schema_1_person.py:3()
*question*
why the same callback function (comparing login_onfail (not executed) and 
before_insert_person (executed) ) ?
as you see in my step above, i just trying to hit http://127.0.0.1:8000/z, 
no trying to login or insert the new record of table person

*another question is about validator*
e.g.
requires_person = IS_IN_DB(db, db.person.id, db.person._format)

the above code works when put in models and controllers, why i can't put it 
on modules, it's return an error, is there any way to put it on modules 
using web2py way?
*modules/test_field_constructor.py*
requires_person = IS_IN_DB(current.db, current.db.person.id, 
current.db.person._format)* # return an error*

thanks and best regards,
stifan

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-26 Thread Anthony
On Saturday, March 25, 2017 at 6:05:14 PM UTC-4, 黄祥 wrote:
>
> i mean that callback function is called when i hit the default/user login 
> screen
> btw, your explaination about login_onfail is clear enough, but when 
> compare to the 2nd example, i've bit confused :
> assuming the login_onfail is the callback function and not executed when 
> it's hit login screen (not login yet), so why _before_insert function is 
> executed, when i call the controller (e.g. SQLFORM.grid(db.person) )? 
> just call the controller, not add the record yet.
>

_before_insert will only be called when you do an insert. Probably it is 
not really be called and you think it is (how are you determining that it 
is being called?), or there is some code doing an insert somewhere. Hard to 
say without seeing more details of your code and understanding how you are 
making your observations.

Anthony

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-25 Thread 黄祥
i mean that callback function is called when i hit the default/user login 
screen
btw, your explaination about login_onfail is clear enough, but when compare 
to the 2nd example, i've bit confused :
assuming the login_onfail is the callback function and not executed when 
it's hit login screen (not login yet), so why _before_insert function is 
executed, when i call the controller (e.g. SQLFORM.grid(db.person) )? 
just call the controller, not add the record yet.
yes, the lazy_tables = True in models/db.py 

thanks and best regards,
stifan

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: put function on models or modules

2017-03-25 Thread Anthony
What do you mean by the word "loaded"? Are you expected these functions to 
be executed? They are callback functions that are only executed in 
particular cases. For example, login_onfail will only be executed upon a 
failed login attempt. A table's on_define will be executed when it is fully 
defined (not when initially created if lazy tables are enabled), but 
_before_insert will only be executed when you actually try to insert a 
record.

Anthony

On Saturday, March 25, 2017 at 9:07:20 AM UTC-4, 黄祥 wrote:
>
> just curious what happen when i put function def or lambda on models when 
> running web2py with profiler
> *e.g. 1*
> *models/db.py*
> # login onfail create new record on auth_event
> def login_onfail(form):
> username = request.vars.username
> row = db((db.auth_user.username == username ) ).iterselect(cache = 
> cache_db, 
>   cacheable = True).first()
> if row is not None:
> test_event.onfail_event(row.id, row.username)
>
> auth.settings.login_onfail.append(login_onfail)
>
> why this is not loaded when hit defaults/user (not trying to login yet) 
> (checked during running snakeviz) ?
>
> *e.g. 2*
> *models/db.py*
> def before_insert_person(f):
> if f['auth_user']:
> query_auth_user = (db.auth_user.id == f['auth_user'] )
> row_auth_user = db(query_auth_user).iterselect(cache = (cache.ram, 3600), 
>   cacheable = True).first()
> f['username'] = row_auth_user.username
> f['first_name'] = row_auth_user.first_name
> f['last_name'] = row_auth_user.last_name
> f['email'] = row_auth_user.email
>
> def on_define_person(table): 
> #table._before_insert.append(test_define_table.before_insert_person)
> table._before_insert.append(before_insert_person)
>
> db.define_table('person', 
> Field('is_auth', 'boolean'),
> Field('auth_user', 'reference auth_user'), 
> Field('username'), 
> Field('first_name'), 
> Field('last_name'), 
> Field('email', 'list:string'), 
> on_define = on_define_person, 
> format = lambda r: '%s %s' % (r.first_name, r.last_name) )
>
> when checked during running snakeviz :
> 1. why before_insert_person is loaded when put it on models, and not 
> loaded when put it on modules?
> 2. why on_define is loaded whether put it on models or modules?
>
> any idea or explaination about that?
>
> thanks and best regards,
> stifan
>

-- 
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 the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.