Dependencies and validation.

25 views
Skip to first unread message

annet

unread,
Jan 10, 2009, 11:51:47 AM1/10/09
to web2py Web Framework
I am still searching for an elegant multi column unique constraint
solution.

My model reads like:

db=SQLDB('sqlite://annet.db')

db.define_table('shape',
SQLField('name'),
migrate='shape.table')

db.define_table('color',
SQLField('name'),
migrate='color.table')

db.define_table('shapecolor',
SQLField('shapename'),
SQLField('colorname'),
SQLField('shapecolor'),
migrate='shapecolor.table')

db.shapecolor.shapename.requires=IS_IN_DB(db,db.shape.name,'%(name)s')
db.shapecolor.colorname.requires=IS_IN_DB(db,db.color.name,'%(name)s')
db.shapecolor.shapecolor.requires=IS_NOT_IN_DB
(db,'shapecolor.shapecolor')


When, in appadmin I insert circle blue and manually add circleblue
twice the validator works. So, I wrote the following function in the
default controller:

def index():
from gluon.sqlhtml import form_factory
form=SQLFORM(db.shapecolor,fields=['shapename','colorname'])
form.vars.shapecolor=str(form.vars.shapename)+str
(form.vars.colorname)
if form.accepts(request.vars,session):
response.flash='form accepted'
elif form.errors:
response.flash='form has errors (a shape with this color
already exists)'
else:
response.flash='please fill the form'
return dict(form=form)

When I expose the function and insert circle green twice the validator
doesn't work. When I take a look in database db select the shapecolor
column contains NoneNone twice, so

form.vars.shapecolor=str(form.vars.shapename)+str(form.vars.colorname)

results in NoneNone instead of circlegreen, and the validator doesn't
work, it inserts NoneNone and NoneNone without complaining.

I hope it is possible to implement my idea in web2py, and that one of
you tells me how to code this correctly.


Best regards,

Annet.

mdipierro

unread,
Jan 10, 2009, 12:02:18 PM1/10/09
to web2py Web Framework
form.vars.shapecolor=str(form.vars.shapename)+str
(form.vars.colorname)

should be

form.vars.shapecolor=str(request.vars.shapename)+str
(request.vars.colorname)

because, in your code, this line is executed before validation
(accepts) thus before request.vars values are copied into form.vars
values.

Massimo

annet

unread,
Jan 10, 2009, 12:31:10 PM1/10/09
to web2py Web Framework
Massimo,

Thanks for your instant reply. Changing form.vars to request.vars
solved one of the problems, the shape color combinations are now
inserted in the database properly, however, the validator doesn't
work. Which is rather strange because it does work in the default
interface, that is when I insert a record through database db table
shapecolor. I hope you have an idea why this happens.


Best regards,

Annet.

mdipierro

unread,
Jan 10, 2009, 3:16:15 PM1/10/09
to web2py Web Framework
because the assignment is done after validation.

Massimo

annet

unread,
Jan 11, 2009, 3:55:21 AM1/11/09
to web2py Web Framework
Massimo,

So, even though form.vars.shapecolor=str(request.vars.shapename)+str
(request.vars.colorname) comes first in the following code:


def index():
from gluon.sqlhtml import form_factory
form=SQLFORM(db.shapecolor,fields=['shapename','colorname'])
form.vars.shapecolor=str(request.vars.shapename)+str
(request.vars.colorname)
if form.accepts(request.vars,session):
response.flash='form accepted'
elif form.errors:
response.flash='form has errors (a shape with this color
already exists)'
else:
response.flash='please fill the form'
return dict(form=form)


... the assignment is done after validation. I thought that
form.accepts(request.vars,session) would take care of validating all
three variables. I there another way to validate shapecolor?


Best regards,

Annet.

mdipierro

unread,
Jan 11, 2009, 11:39:51 AM1/11/09
to web2py Web Framework
accepts only validates field variables in fields=[...] upon moving
them from request.vars into form.vars. field variables that are
computed programmatically (as in your case) cannot be validated since
web2py cannot report the error to the user via the form.

There are ways around this. For example

form=SQLFORM(db.shapecolor,fields=['shapename','colorname'])
shapecolor=str(request.vars.shapename)+str
(request.vars.colorname)
form.vars.shapecolor,form.errors.shapecolor=\
db.shapecolor.shapecolor.requires(shapecolor)
if form.errors.shapecolor:
response.flash=form.errors.shepcolor ### notify user
elif form.accepts(request.vars,session):
....

Massimo

annet

unread,
Jan 11, 2009, 12:24:57 PM1/11/09
to web2py Web Framework
Massimo,

Thanks for helping me solve this problem, it works!

I use this solution to solve the multi column unique constraint
problem, it may not be the most elegant solution, but I prefer this
one over the one of coding widgets to repair all the broken drop
boxes.

I have one last questions about this: what exactly does the following
line of code accomplish?

form.vars.shapecolor,form.errors.shapecolor=db.shapecolor.shapecolor.requires
(shapecolor)


Annet.

mdipierro

unread,
Jan 11, 2009, 12:50:43 PM1/11/09
to web2py Web Framework
It calls explicitly the validator you defined for
db.shapecolor.shapecolor.requires
It return (value,error), error==None if not error.
Reply all
Reply to author
Forward
0 new messages