Latest Version: 0.9.6.2
  Dashboard > Pylons Cookbook > ... > Controllers > Handling tables with many fields
  Pylons Cookbook Log In | Sign Up   View a printable version of the current page.  
  Handling tables with many fields
Added by Mike Orr, last edited by Mike Orr on Jun 10, 2008
Labels: 
(None)

If you have a table with fifty or more fields, you may get tired of repeating them again and again. This shortcut saves typing and also minimizes mismatch errors.

Controller

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import pprint
from myapp.model import MyORMClass

class MyController(BaseController):
    def _update_my_attributes(self, my_object):
        data = self.form_result
        log.debug("form input = %s", pprint.pformat(data))
        my_object.field1 = data["field1"]
        ...

        # Or if you prefer to use a loop.
        fieldnames = [x.name for x in MyORMClass.c]
        for fieldname in fieldnames:
            value = data[fieldname]
            setattr(my_object, fieldname, value)


    @validate(schema=SomeSchema(), form="new")
    def create(self):
        my_object = MyORMClass()
        self._update_my_attributes(my_object)
        meta.Session.save(my_object)
        meta.Session.flush()  # Write the object so it has a primary key.
        assert my_object.id, "Failed to add MyORMClass to database."
        meta.Session.commit()
        redirect_to(... display page ...)

    @validate(schema=SomeSchema(), form="edit")
    def update(self):
        my_object = MyORMClass.get(PRIMARY_KEY_THAT_I_KNOW_SOMEHOW)
        self._update_my_attributes(my_object)
        meta.Session.commit()
        redirect_to(... display page ...)

Generic function

If you want to make this even more generic, you can replace ._update_my_attributes with a function:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def update_orm_instance(instance, data):
    """Update a new or existing ORM instance from user input.

    ``instance`` is a SQLAlchemy ORM instance (mapped class).
    ``data`` is a dict of user input whose keys correspond to ``instance`` attributes.
    """
    fieldnames = [x.name for x in instance.__class__.c]
    for fieldname in fieldnames:
        value = data[fieldname]
        setattr(my_object, fieldname, value)

Commentary

Fieldname loops may look convenient but they're kind of magical, and they don't provide any way to customize certain fields; e.g., to convert the value to another type, skip certain fields, set values in related tables, etc. Still, if your needs are straightforward, this might be a pattern for you.

Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators
Top