Links to referencing records

Now consider the case of two tables linked by a reference field. For example:

1 db.define_table('person',

3 db.define_table('dog',

6 db.dog.owner.requires = IS_IN_DB (db,db.person.id, 'i(name)s')

A person has dogs, and each dog belongs to an owner, which is a person. The dog owner is required to reference a valid db.person.id by '%(name)s'.

Let's use the appadmin interface for this application to add a few persons and their dogs.

When editing an existing person, the appadmin UPDATE form shows a link to a page that lists the dogs that belong to the person. This behavior can be replicated using the linkto argument of the sqlform. linkto has to point to the URL of a new action that receives a query string from the sqlform and lists the corresponding records. Here is an example:

1 def display_form():

2 if len(request.args):

3 records = db(db.person.id==request.args[0]).select()

4 if len(request.args) and len(records):

7 form = SQLFORM(db.person, records[0], deletable=True,

8 upload=url, linkto=link)

9 else:

10 form = SQLFORM (db.person)

11 if form.accepts (request.vars, session):

12 response .flash = 'form accepted'

13 elif form.errors:

14 response .flash = 'form has errors'

15 return dict(form=form)

Here is the page:

There is a link called "dog.owner". The name of this link can be changed via the labels argument of the sqlform, for example:

1 labels = { 'dog.owner' : "'This person's dogs"}

If you click on the link you get directed to:

1 /test/default/list_records/dog?query=dog.owner%3D5

"list_records" is the specified action, with request .args [o] set to the name of the referencing table and request.vars.query set to the SQL query string. The query string in the URL contains the value "dog.owner=5" appropriately url-encoded (web2py decodes this automatically when the URL is parsed).

You can easily implement a very general "list_records" action as follows:

1 def list_records():

2 table = request.args[0]

3 query = request.vars.query

4 records = db(query),select(db[table].ALL)

5 return dict(records=records)

with the associated "default/lisLrecords.html" view:

When a set of records is returned by a select and serialized in a view, it is first converted into a SQLTABLE object (not the same as a Table) and then serialized into an HTML table, where each field corresponds to a table column.

Was this article helpful?

0 -1

Post a comment