athinker
athinker

Reputation: 71

How to update the database using sqlform through a service call

I wanted to know how to update the database using sqlform through a service call. for example

db.py contains

db.define_table('person',
Field('name'),
Field('email'))

controller contains

@service.run
def display_form():
form = SQLFORM(db.person)
if form.accepts(request.vars):
    return "success"
else:
    return "failure"

The http post variable is sent as data = {"name":"xyz", "email":"[email protected]"}

I would like to know whether I am sending the post variables correctly. I always get the failure message. WHY IS THE DB NOT GETTING UPDATED. Actually I would like to do this with form = auth.register(). I need to enter the auth table values through a service call. but this is long way to go.

Update

This is the way I am posting.

url = "http://example.com/myapp/mycontroller/api/person"
data = {"name":"peter","email":"[email protected]"}
datatosend = urllib.urlencode(data)
request = urllib2.Request(url,datatosend)
res = urllib2.urlopen(req)

but the POST method in api is not seeing the person at all.

Upvotes: 0

Views: 1028

Answers (1)

Anthony
Anthony

Reputation: 25536

When you create a form via SQLFORM, a special hidden _formname field is added to the form. If the posted data does not include a matching _formname field, the form.accepts() method will fail. In place of the default formname, you can specify your own, and add it to the posted data:

@service.run
def display_form():
    request.vars._formname = 'myform'
    form = SQLFORM(db.person)
    if form.accepts(request.vars, formname='myform'):
        return 'success'
    else:
        return 'failure'

However, a much simpler method is to avoid the form altogether and directly insert the record (still taking advantage of the validation process by using the validate_and_insert method):

@service.run
def display_form():
    return db.person.validate_and_insert(**request.vars)

This will return the inserted record ID if successful or validation errors otherwise.

An alternative to @service.run is the new RESTful web services functionality:

@request.restful()
def api():
    def POST(tablename, **fields):
        if not tablename == 'person': raise HTTP(400)
        return db.person.validate_and_insert(**fields)
    return locals()

Then insert a record via a POST request to:

http://mydomain.com/myapp/mycontroller/api/person

Upvotes: 1

Related Questions