Override data/update SQLFORM behavior

23 views
Skip to first unread message

Gary

unread,
Apr 26, 2009, 7:37:03 PM4/26/09
to web2py Web Framework
Is there a simple way to replace the automatically generated SQLFORM
in the various crud controllers with a custom SQLFORM?

Thanks.

mdipierro

unread,
Apr 26, 2009, 9:22:40 PM4/26/09
to web2py Web Framework
Yes, you can make the form in html as usual for SQLFORM.

Gary

unread,
Apr 27, 2009, 4:14:16 PM4/27/09
to web2py Web Framework
Like myapp/default/display_manual_form() in the book, right?

Two questions. I assume that I need a:

def data(): return dict(form=crud())

for each table that uses the crud controller to properly define the
URL. If that's true, it's the part that I missed.

Second, is it better to call the update directly like:

1) http://hostname/myapp/default/data/update/person/2

or create a controller like:

2) def update1():
redirect(URL(r=request,f='data/update/person/2'))

In either case, what should the view be named? Since one might want
to have a different view for read,update,delete,etc., it seems that it
should be:

default/data/update.html, but my testing seems to work at default/
data.html.

That seems to imply that using method #2 above with a response.view()
would be the better solution. Would you agree with that conclusion or
is there a better way to handle this?

Thank you.
Gary

mdipierro

unread,
Apr 27, 2009, 5:48:52 PM4/27/09
to web2py Web Framework
On Apr 27, 3:14 pm, Gary <gary.k.ma...@gmail.com> wrote:
> Like myapp/default/display_manual_form() in the book, right?
>
> Two questions. I assume that I need a:
>
> def data(): return dict(form=crud())
>
> for each table that uses the crud controller to properly define the
> URL. If that's true, it's the part that I missed.

No. This controller will work for every table in the database. In
fact, as you do below, you specify the table in the URL

> 1)http://hostname/myapp/default/data/update/person/2

You create a CRUD action per table

def mycreate():
return dict(form=crud.create(db.mytable))

or an update action

def myupdate():
id=request.args[0]
return dict(form=crud.update(db.mytable,id))



> or create a controller like:
>
> 2) def update1():
> redirect(URL(r=request,f='data/update/person/2'))

Do do not do actions that just redirect.

> In either case, what should the view be named?

the view is the controller/action.html

> Since one might want
> to have a different view for read,update,delete,etc., it seems that it
> should be:
>
> default/data/update.html, but my testing seems to work at default/
> data.html.

you can do

def data():
response.view="%s/%s/%s.html" % (request.controller,
request.function, request.args[0])
return dict(form=crud())

Gary

unread,
Apr 27, 2009, 6:23:28 PM4/27/09
to web2py Web Framework
Massimo,

Thank you, Thank you, Thank you! This clarified so much and makes a
great deal of sense.

Kindest regards,
Gary

mdipierro

unread,
Apr 27, 2009, 6:31:17 PM4/27/09
to web2py Web Framework
when you call crud you can also specify lots of options...

def mycreate():
return dict(form=crud.create(db.mytable,next=URL
(...),onaccept=lambda form:pass,onvalidation=lambda form: pass))

and more. You can also embed them in views

{{=crud.create(db.mytable)}}

Massimo

Gary

unread,
Apr 27, 2009, 7:44:28 PM4/27/09
to web2py Web Framework
It's going to take some time to digest this, especially the
onxxx=lambda part. When would you use the embedded form rather than
the controller/view combination above? Are there any examples of the
either (or both) the these? If not, once I understand this better,
I'd be happy to contribute to the documentation.

Thanks again,
Gary

Álvaro Justen [Turicas]

unread,
Apr 27, 2009, 8:15:08 PM4/27/09
to web...@googlegroups.com
.On Mon, Apr 27, 2009 at 8:44 PM, Gary <gary.k...@gmail.com> wrote:
> It's going to take some time to digest this, especially the
> onxxx=lambda part.  When would you use the embedded form rather than
> the controller/view combination above?  Are there any examples of the
> either (or both) the these?  If not, once I understand this better,
> I'd be happy to contribute to the documentation.

http://docs.python.org/tutorial/controlflow.html#lambda-forms

--
Álvaro Justen
Peta5 - Telecomunicações e Software Livre
21 3021-6001 / 9898-0141
http://www.peta5.com.br/

Gary

unread,
Apr 29, 2009, 8:52:01 AM4/29/09
to web2py Web Framework
Sorry for being so long winded.
I've been trying to implement a custom html form using the crud
applications as explained above, but I'm having difficulty using
custom html. Here is the test MVC that I've created for the purpose
of understanding the concepts:

Model
--------
try:
from gluon.contrib.gql import * # if running on Google App Engine
except:
db = SQLDB('sqlite://storage.db') # if not, use SQLite or other
DB
else:
db = GQLDB() # connect to Google BigTable
session.connect(request, response, db=db) # and store sessions
there
##
db.define_table('testtable',SQLField('testfield1','string'),SQLField
('testfield2','string'))

from gluon.tools import Mail, Auth, Crud # new in web2py 1.56
crud=Crud(globals(),db) # for CRUD helpers using
auth
crud.settings.update_next = URL(r=request, f='index')
=====

Controller
------------
def index():
redirect(URL(r=request,f='testupdate',args=["1"]))

def testupdate():
id=request.args[0]
return dict(form=crud.update(db.testtable,id))

def data():
response.view="%s/%s/%s.html" %
(request.controller,request.function, request.args[0])
return dict(form=crud())

=======

View (default/testupdate.html)

{{extend 'layout.html'}}
<h1>This is the default/testupdate.html template</h1>

<!-- Try the form (Works)-->
{{=form}}

<!--Try individual form fields (Submit doesn't work)-->
{{for field in form:}}
{{=field}}
{{pass}}

<!-- Try the form by duplicating form output (Submit doesn't work)-->
<table>
<tr id="testtable_testfield1__row">
<td><label for="testtable_testfield1"
id="testtable_testfield1__label">Testfield1: </label></td>
<td><input class="string" id="testtable_testfield1"
name="testfield1" type="text" value="testdata1" /></td>
<td></td>
</tr>
<tr id="testtable_testfield2__row">
<td><label for="testtable_testfield2"
id="testtable_testfield2__label">Testfield2: </label></td>
<td><input class="string" id="testtable_testfield2"
name="testfield2" type="text" value="testdata2" /></td>
<td></td>
</tr>
<tr id="delete_record__row">
<td><label for="delete_record" id="delete_record__label">Check to
delete:</label></td>
<td><input class="delete" id="delete_record"
name="delete_this_record" type="checkbox" value="on" /></td>
<td></td></tr><tr id="submit_record__row"><td></td><td><input
type="submit" value="Submit" /></td>
<td></td>
</tr>
</table>
<div class="hidden"><input name="_next" type="hidden" value="http://
localhost:8001/test/default/testupdate/1" />
<input name="id" type="hidden" value="1" />
<input name="_formkey" type="hidden" value="b7418550-1b4a-434b-
bdc1-84a24e904582" />
<input name="_formname" type="hidden" value="testtable_1" />
</div>
</form>

========

It's obvious that the hidden field 'formname' is required and changes
with each submission. I assume that there is a value that can be
inserted there to fix that problem, but is this the best/only way to
gain full control of the display of a crud application? Any insight
will be greatly appreciated.

Thanks,
Gary

====================================================================
====================================================================



On Apr 27, 6:31 pm, mdipierro <mdipie...@cs.depaul.edu> wrote:
Reply all
Reply to author
Forward
0 new messages