views:

1202

answers:

5

I'm a firm believer of the heretic thought of tight coupling between the backend and frontend: I want existing, implied knowledge about a backend to be automatically made use of when generating user interfaces. E.g., if a VARCHAR column has a maximum with of 20 characters, there GUIs should automatically constrain the user from typing more than 20 characters in a related form field.

And I have strong antipathy to ORMs which want to define my database tables, or are based on some hack where every table needs to have extra numeric ID columns because of the ORM.

I've looked a bit into Python database frameworks and I think I can conclude the SQLAlchemy fits best to my mentality.

Now, I need to find a web application framework which fits naturally with SQLAlchemy (or an equivalent) and perhaps even with my appetite for coupling. With "web application framework", I mean products/project such as Pyhons, Django, TurboGears, web2py, etc.

E.g., it should ideally be able to:

  • automatically select a suitable form widget for data entering a given column if told to do so; e.g., if the column has a foreign key to a column with 10 different values, widget should display the 10 possible values as a dropdown
  • auto-generate javascript form validation code which gives the end-user quick error feedback if a string is entered into a field which is about to end up in an INTEGER column, etc
  • auto-generate a calendar widget for data which will end up in a DATE column
  • hint NOT NULL constraints as javascript which complains about empty or whitespace-only data in a related input field
  • generate javascript validation code which matches relevant (simple) CHECK-constraints
  • make it easy to avoid SQL injection, by using prepared statements and/or validation of externally derived data
  • make it easy to avoid cross site scripting by automatically escape outgoing strings when appropriate
  • make use of constraint names to generate somewhat user friendly error messages in case a constrataint is violated

All this should happen dynamically, so table adjustments are automatically reflected on the frontend - probably with a caching mechanism, so that all the model introspection wouldn't kill performance. In other words, I don't want to repeat my model definition in an XML file (or alike) when it has already been carefully been defined in my database.

Does such a framework exist for Python (or for any language, for that matter)? If not: Which of the several Python web application frameworks will be least in the way if I were to add parts of the above features myself?

+3  A: 

You should have a look at django and especially its newforms and admin modules. The newforms module provides a nice possibility to do server side validation with automated generation of error messages/pages for the user. Adding ajax validation is also possible

Peter Hoffmann
Does Django play nicely with SQLAlchemy, though? Last I'd heard, the Django+SA branch was moribund, and the original question specified SA as the ORM of choice.
Tim Lesher
+1  A: 

I believe that Django models does not support composite primary keys (see documentation). But perhaps you can use SQLAlchemy in Django? A google search indicates that you can. I have not used Django, so I don't know.

I suggest you take a look at:

I do not have any deep knowledge of any of the projects above. I am just in the process of trying to add something similar to one of my own applications as what the original question mentions. The above list is simply a list of interesting projects that I have stumbled across.

As to web application frameworks for Python, I recommend TurboGears 2. Not that I have any experience with any of the other frameworks, I just like TurboGears...

If the original question's author finds a solution that works well, please update or answer this thread.

codeape
+1  A: 

TurboGears currently uses SQLObject by default but you can use it with SQLAlchemy. They are saying that the next major release of TurboGears (1.1) will use SQLAlchemy by default.

andy47
+1  A: 

I know that you specificity ask for a framework but I thought I would let you know about what I get up to here. I have just undergone converting my company's web application from a custom in-house ORM layer into sqlAlchemy so I am far from an expert but something that occurred to me was that sqlAlchemy has types for all of the attributes it maps from the database so why not use that to help output the right html onto the page. So we use sqlAlchemy for the back end and Cheetah templates for the front end but everything in between is basically our own still.

We have never managed to find a framework that does exactly what we want without compromise and prefer to get all the bits that work right for us and write the glue our selves.

Step 1. For each data type sqlAlchemy.types.INTEGER etc. Add an extra function toHtml (or many maybe toHTMLReadOnly, toHTMLAdminEdit whatever) and just have that return the template for the html, now you don't even have to care what data type your displaying if you just want to spit out a whole table you can just do (as a cheetah template or what ever your templating engine is).

Step 2

<table>

<tr>

#for $field in $dbObject.c:

<th>$field.name</th>

#end for

</tr>

<tr>

#for $field in dbObject.c:

<td>$field.type.toHtml($field.name, $field.value)</td>

#end for

</tr>

</table>

Using this basic method and stretching pythons introspection to its potential, in an afternoon I managed to make create read update and delete code for our whole admin section of out database, not yet with the polish of django but more then good enough for my needs.

Step 3 Discovered the need for a third step just on Friday, wanted to upload files which as you know needs more then just the varchar data types default text box. No sweat, I just overrode the rows class in my table definition from VARCHAR to FilePath(VARCHAR) where the only difference was FilePath had a different toHtml method. Worked flawlessly.

All that said, if there is a shrink wrapped one out there that does just what you want, use that.

Disclaimer: This code was written from memory after midnight and probably wont produce a functioning web page.

Jason
+5  A: 

web2py does most of what you ask:

Based on a field type and its validators it will render the field with the appropriate widget. You can override with

db.table.field.widget=...

and use a third party widget.

web2py has js to blocks the user from entering a non-integer in a integer field or a non-double in a double field. time, date and datetime fields have their own pickers. These js validation work with (not instead) of server side validation.

There is IS_EMPTY_OR(...) validator.

The DAL prevents SQL injections since everthing is escaped when goes in the DB.

web2py prevents XSS because in {{=variable}}, 'variable' is escaped unless specified otherwise {{=XML(variable)}} or {{=XML(variable,sanitize=True)}}

Error messages are arguments of validators for example

db.table.field.requires=IS_NOT_EMPTY(error_message=T('hey! write something in here'))

T is for internationalization.

massimo