New Manipulators and Validation Aware models.

18 views
Skip to first unread message

Brantley Harris

unread,
Aug 21, 2006, 6:53:38 PM8/21/06
to django-d...@googlegroups.com
I have built a proposal for a new Manipulator system. Here are some
of the benefits of this new system:

- Custom form views become very simple, and intuitive.
- Validation aware models are harnessed.
- Forms are raised as an exception. This allows the writer to assume
the data is correct the whole way through. However, when there is a
validation exception, it is handled easily.

The proposal can be found here:
http://code.djangoproject.com/wiki/NewManipulators

Here is a sample view using a default CreateManipulator:
def create_poll(request):
try:
m = Poll.CreateManipulator()
poll = m.process(request)
return HttpResponseRedirect('/poll/%d/' % poll.id)
except Form, form:
return render_to_response('poll/create.html', {'form': form})

Feedback and criticism would be greatly appreciated.

Andrew Durdin

unread,
Aug 22, 2006, 5:02:53 AM8/22/06
to Django developers
Brantley Harris wrote:
>
> Here is a sample view using a default CreateManipulator:
> def create_poll(request):
> try:
> m = Poll.CreateManipulator()
> poll = m.process(request)
> return HttpResponseRedirect('/poll/%d/' % poll.id)
> except Form, form:
> return render_to_response('poll/create.html', {'form': form})

Raising the form as an exception is an interesting alternative to the
normal "if posted and everything validates, redirect, else render form"
approach.

I've also embarked on a quest to improve the situation with
manipulators, although I've taken a much more radical approach. I
intend to do a full writeup in a couple of days when I've filled a few
holes in the code, but here's a quick summary of the path I've taken:

I first wanted a way to easily create forms that were minor variations
on other forms; in particular, to be able to replace one or two widgets
(I've named the form field classes *Widgets to avoid confusion with the
database *Field classes) from the default form for a model class with
other widgets. So I created a Form class, that is subclassed to allow
a declarative-style form specification. Form subclasses can further be
subclassed to change or add widgets.

The second need I had was to allow forms to easily manipulate data that
wasn't in models. So the data from Form instances is first saved into
a structure of dicts and lists (a single dict for a form with no nested
subforms). The widget-level validation (e.g. ensuring that the user has
entered the same password in both text input elements) happens on this
data. Of course, forms that directly manipulate models are important
too: so a model instance can be updated from this data. The important
feature with all this is that forms can have nested subforms and lists
of subforms that are the equivalent of edit_inline, and updating the
model instance correctly handles foreign keys and many to many
relationships. Of course, all the above uses model validation as well.

The third need I had was to be able to customise the appearance and/or
client-side behaviour of all input elements in a site; so all Widgets
use template-based rendering. In an individual project, I can then
create new template files that will be used instead of the default
templates.

One final part of all this was the removal of the
AddManipulator/ChangeManipulator dichotomy -- the two are functionally
equivalent, with the only difference being that the form data is
populated from and saved into a newly created model instance vs. one
retrieved from the database.

Because these changes involve removing or rewriting significant
portions of django.forms, and thoroughly break compatibility with the
existing manipulators, I'll be releasing it as a separate module rather
than a patch to django.

Andrew

Reply all
Reply to author
Forward
0 new messages