Friday, October 24, 2008

A small admin app for Pylons

I said that it would be possible to build a django-style admin interface for Pylons using FormAlchemy. (That is, generate a UI for basic CRUD operations for all your models, with no further configuration necessary.) I have a proof of concept in FA svn; it's missing some obvious features like internationalization so there is no official release yet. But the basics are there, so in the meantime, if you'd like to kick the tires, just install FA from svn and give it a try.

Here are some screenshots from a pylons app incorporating models from the FA test suite. (The admin controller is fully customizable using standard FA (and Pylons) techniques, but these are what you'd see out-of-the-box.)

Index: Order page: Creating a new Order: Deleting an Order: The User page: Editing a User instance: Documentation on using and customizing the pylons admin app is here.

Thursday, October 16, 2008

FormAlchemy 1.0

A little background: a few months ago, I went looking for a web framework that was good at automating CRUD (create/retrieve/update/delete) against an existing database schema. I tried django but its database introspection abilities are beyond feeble, and django-sqlalchemy was not mature enough. I tried dbmechanic but its dozen-plus dependencies, most of which were alpha-quality, gave me pause; so did its basic architecture on top of toscawidgets, which I think is The Wrong Way to build web apps. (I understand that the former problem has since been reduced; the latter has not.)

So, I went back to option #3, FormAlchemy. I knew SQLAlchemy could reflect very hairy schemas indeed, and what it could not reflect, it could certainly represent with a little manual help. And FormAlchemy was a decent start to automating CRUD with SA models. I added the ability to represent relations, automatic syncing of form input back to SA objects, Grid support, and a test suite. Then Gael came along and added internationalization, support for even more SA features, and Sphinx docs. Along the way we've killed enough bugs and added enough test cases (yes, the two are related) that we think we have a pretty solid release. Especially since I just released 1.0.1 fixing the most obvious problems. :)

I think all three FA committers use it mostly with Pylons; that said, FormAlchemy has no dependencies besides SQLAlchemy itself. You could easily use it with werkzeug or or whatever.

Here, finally, is a quick FormAlchemy tutorial:

To get started, you only need to know about two classes, FieldSet and Grid, and a handful of methods:

  • render: returns a string containing the html
  • validate: true if the form passes its validations; otherwise, false
  • sync: syncs the model instance that was bound to the input data

This introduction illustrates these three methods. For full details on customizing FieldSet behavior, see the documentation.

We'll start with two simple SQLAlchemy models with a one-to-many relationship (each User can have many Orders), and fetch an Order object to edit:

 from formalchemy.tests import Session, User, Order
session = Session()
order1 = session.query(Order).first()

Now, let's render a form to edit the order we've loaded.

 from formalchemy import FieldSet, Grid
fs = FieldSet(order1)
print fs.render()

This results in the following form elements:

Note how the options for the User input were automatically loaded from the database. str() is used on the User objects to get the option descriptions.

To edit a new object, bind your FieldSet to the class rather than a specific instance:

  fs = FieldSet(Order)

To edit multiple objects, bind them to a Grid instead:

 orders = session.query(Order).all()
g = Grid(Order, orders)
print g.render()

Which results in:

Saving changes is similarly easy. (Here we're using Pylons-style request.params(); adjust for your framework of choice as necessary):

 fs = FieldSet(order1, request.params())
if fs.validate():

Grid works the same way. More details in the documentation; start with Form generation.

To give FormAlchemy a try, just easy_install it. If you have any questions, Alex and I are often in both #sqlalchemy and #pylons on freenode. And of course there's always the mailing list.