Form handling in Pyramid

336 views
Skip to first unread message

Mike Orr

unread,
Jan 17, 2011, 2:23:00 PM1/17/11
to pylons-...@googlegroups.com, pylons...@googlegroups.com, Ian Bicking, Mark Ramm, Chris Perkins
As part of the Pylons-to-Pyramid howto I'm writing, I need to make
some recommendations for form handling. This covers the sprawling
topic of form generation, validation, error display, usage pattern in
the view, and side topics such as database records,
internationalization, and REST resources.

Pylons 1 includes a minimum form pattern based FormEncode, WebHelpers,
and @validate. Pyramid does not have any form dependencies; it's up to
you to choose a library. A baseline scenario using the closest
equivalent gives us:

Form creation: WebHelpers HTML tags
Validation: FormEncode
Error display: FormEncode htmlfill
Usage: pyramid_simpleform (new package by zeemonkey)
Usage: two-view (one for form, another for submission)
Database records: WebHelpers ModelTags
Internationalization: FormEncode messages property
REST: pyramid_routehelper (not written yet; equivalent to Routes
map.resource)

This does everything except form generation; instead it provides
helpers to create your own form in your template. The question is, is
this still the best usage pattern to promote in 2011, and if so, are
these the best packages to do it? I also need to survey the various
alternative form packages and rank them into beginner/advanced, and
note how widely used and supported they are. So this email is to
collect feedback for that: what are people using, and what do they
think makes sense for Pyramid.

My own feeling is to stick with this pattern as the first
recommendation. It's pyramidesque and flexible. Mako has a
call-with-content feature and a new unobtrusive syntax that allows
template functions to look almost like built-in template commands; we
have never sufficiently explored this as a basis for a form library. I
also like how FormEncode's validators can be used generally for
validation and conversion: I use them to check and transform the INI
settings at startup. I also use formencode.declarative as a general
base class because it handles constructor args for you.

However, FormEncode is 6+ years old, its documentation is somewhat
confusing for using it in a Pylons/Pyramid context, some things are
undocumented, and the source has some code that looks like dead ends
(backward compatibility only). I've been meaning to write a new
FormEncode manual for years but have never had time to. So maybe it's
time to streamline it into a new package.

Which brings us to Formish and Deform. At first glance, Formish seems
to be a streamlining of FormEncode into discrete classes for schemas,
validation, type conversion (which it separates from validation), with
specific support for nested form data and file uploads. It also adds a
layer for form generation using Mako. Deform, by our own ChrisM, is a
reimplementation of the Formish concept using different libraries and
Chameleon templates.

So, for those who've used them, is this true? Are they equivalent to
FormEncode, or are they missing any of FormEncode's functionality? How
well does it work separating validation from type conversion? To me it
seems like you have to type convert in order to validate, and a failed
conversion is a failed validation, so I don't really see the point in
separating them, and I'm concerned the schema definitions may be more
verbose than FormEncode's is. Has there been any work on Mako
templates for Deform? What has users' experience with these libraries
been?

There's also WTForms, which we considered recently for Pylons 2. It
has a simple interface like Django newforms which we liked, but it
wasn't as flexible as FormEncode and the validators seemed like they
weren't designed for non-web use, so we were afraid of losing some
existing functionality. Is anyone using WTForms with Pylons or Pyramid
who would like to comment?

ToscaWidgets has always been popular but has been reputed as harder to
learn and bigger, so it seems to belong to the "advanced forms"
category.

Then there are several form/model generators tied to SQLAlchemy, such
as FormAlchemy, GeoFormAlchemy, Sprox (which seems to have replaced
DBSprockets?), etc. I'm not sure of the differences between these.
Those tied to SQLAlchemy are subset of form generation, so they would
go in a subsection.

Another issue is one-view vs two-view form processing. The tradtional
way (before I came to Pylons) was to use one view with an 'if' that
would display the form if there are no POST variables, or validate it
if there are, and an inner 'if' to do the action if the validation
succeeds, or to redisplay the form with errors if it fails. Pylons
@validate went with a two-form approach, which means you have to call
the form view from the submission view if the validation fails. And
REST essentially requires a two-vlew approach because the form and
submission are on different URLs, and the same URL is doubled up for
submitting one form (PUT or POST) and displaying a different page
(GET). So different URLs for form and submission require two views.
Most people have kept the two-view approach with @validate even for
non-REST forms. I think it would be best to support both approaches,
two-view and one-view.

One thing I was concerned about in pyramid_simpleform
(http://packages.python.org/pyramid_simpleform/) is that the view
handler has the form view and submission view that look almost the
same. It's like one could go to either URL? What's the purpose of
this, and how does it handle the case of failed validation?

Anyway, if you have any ideas on what should be in the Pyramid-Pylons
form howto (which will probably be the Pyramid form howto too, since
there isn't one of those I could find), now's the time to speak up.

--
Mike Orr <slugg...@gmail.com>

Gael Pasgrimaud

unread,
Jan 17, 2011, 3:27:32 PM1/17/11
to pylons-...@googlegroups.com, pylons...@googlegroups.com
Hi,

I don't really have something to say because I'm using FormAlchemy for
years now and it work fine with pyramid (and all webob based
application) too so I will continue to use it.
So I'm really not objective. I just want to end up the misunderstanding.

On Mon, Jan 17, 2011 at 8:23 PM, Mike Orr <slugg...@gmail.com> wrote:
(...)


>
> Then there are several form/model generators tied to SQLAlchemy, such
> as FormAlchemy, GeoFormAlchemy, Sprox (which seems to have replaced
> DBSprockets?), etc. I'm not sure of the differences between these.
> Those tied to SQLAlchemy are subset of form generation, so they would
> go in a subsection.
>

That's not true. FormAlchemy does not rely on SQLAlchemy although it
is a required dependency.
I've wrote some subclass of FormAlchemy's Field and FieldSet to
implement other backends.

As an example there is an implementation for zope.schema:

from formalchemy.ext.zope import FieldSet
from zope.interface import Interface, implements
from zope import schema

class IObj(Interface):
id = schema.TextLine()

class Obj(object):
implements(IObj)

fs = FieldSet(IObj)
obj = Obj()
fs.rebind(obj, data={'Obj--id': 'my id'})
if fs.validate():
fs.sync()
assert obj.id == 'my id'
print fs.render()

This will output:

<div>
<label class="field_req" for="Obj--id">id</label>
<input id="Obj--id" name="Obj--id" type="text" value="my id" />
</div>

<script type="text/javascript">
//<![CDATA[
document.getElementById("Obj--id").focus();
//]]>
</script>

You can read more about this in the documentation:
http://docs.formalchemy.org/formalchemy/ext/zope.html

There is also a ldap implementation not listed in the documentation:
http://pypi.python.org/pypi/afpy.ldap

But... this is totally out of topic. Sorry for the noise.

Regards,

--
Gael

cd34

unread,
Jan 17, 2011, 8:04:54 PM1/17/11
to pylons-discuss
FormEncode allows me to build forms right from the schema. At this
point, if you need something like a GridTable layout, FormEncode is
the only solution I've found.

I moved from Formish to Deform and I find Deform to be quite powerful
and quite good, though I hate the <li> form aspect and much prefer a
tableform layout like ToscaWidgets had. However, Deform works much
better for what I'm working on. I would prefer something a little
more tied to the schema, but, writing two quick hooks. I never liked
the separate action handlers required for ToscaWidgets and much prefer
the single action for create/edit and validate.

To use SQLAlchemy, I wrote two quick functions, though, there are some
minor issues dealing with datetime objects that I haven't handled.

http://cd34.com/blog/framework/using-pyramid-with-deform-to-editcreate-records-in-sqlalchemy-backed-database/

And if you need Formencode validation with Deform, it isn't difficult:

http://cd34.com/blog/framework/using-formencode-for-validation-with-colander-and-deform/

Sharil Shafie

unread,
Jan 18, 2011, 2:54:08 AM1/18/11
to pylons-...@googlegroups.com
I would like to suggest a tutorial on using Deform. I am experimenting
on it, and find it is not too difficult to learn. As a novice and not
actually a 'fulltime programmer', I found out that its integration with
pyramid is quite easy. I am trying to use pyramid_formish, but still can
make sense of it.

TQ.

--
Regards,

-Sharil I. Shafie-

Jonathan Vanasco

unread,
Feb 20, 2011, 7:06:51 PM2/20/11
to pylons-discuss
personally, think it would be best to decouple the moving parts as
much as possible

to me, there is :

html form creation - great if this is baked-in, but it shouldn't be
required
form validation - i think formencode is fine, but i often use it as
a first-pass and then handle things in my controllers too
form submission - validation is only a portion of submission. what
is triggering the validation ? what happens when its a success ? how
about a failure ?

anything else could/should be a module that plugs into the forms.

the old @validate had some issues, but could have been extended into
something more powerful. at least in my usage i was able to separate
out the various phases and provide hooks back into it.
Reply all
Reply to author
Forward
0 new messages