Q:

How much can django.forms help me?

I have the following model which forms a Many-To-Many relationship between Persons and "Eprint" publications. Each person's profile page will show the eprints referenced through this table, but only if show=True, and in the numeric order of the 'order' field:
class UsersEprint(models.Model):
    person = models.ForeignKey(Person)
    eprint = models.ForeignKey(emodels.Eprint) # this has a .title field
    show = models.BooleanField(default=True)
    order = models.IntegerField(default=0)

Now this can all be managed from the admin, but I want a user-friendly form to go in the users profile page on the site.
Ideally I want a table with a row for each of the person's eprints, giving: the eprint title (which can't be edited), a tickbox for 'show', and a numeric field for 'order'. A 'delete' tickbox would be useful too. 
The default approach with modelformsets gives a dropdown chooser for the eprint listing all the eprints - which is because the form doesn't know I don't want to edit this. I've tried various approaches with overriding fields and widgets but it all seems a bit kludgy, and I'm going to have end up rendering the form in the template line-by-line anyway, it seems. 
The next complication is that instead of having the user type numbers to reorder the table rows, I could use a javascript system - either drag'n'drop rows or move up/move down arrows. When the user submits the form, the new order is obtained.
My question is, at what point do I go out of the scope of django's form handling? Should I just drop import django.forms and manage it all myself? Or are there still useful bits in there for even the most awkward forms? 

A:

I don't think your use case is particularly awkward, and I'm sure an InlineModelFormset can handle all your requirements nicely. The thing to remember, is that the primary concern of Django forms is the validation of input data; the presentation is (and should be) up to you.
Sure, Django provides some basic tools for form layout (as_ul et al), but you shouldn't get too hung up on them. Customizing the way your forms are rendered shouldn't be viewed as a "hack", but a feature ;-)

Since you won't be editing the
eprint, you can exclude this field
from the underlying form, which you
pass to
inlinemodelformset_factory; in
your template, just display
form.instance.eprint.title instead
of form.eprint (form.instance
points to the underlying model
instance)
When rendering the forms in the
formset, you can check
form.instance.show -- if it's
True, then render the form
normally. Otherwise, either add a
"hidden" class to the form's
container, or render the fields as
hidden inputs
(form.<FIELD>.as_hidden).
Unfortunately, you can't simply omit
them, as that would cause validation
errors on the server
Passing can_delete=True to
inlinemodelformset_factory will
add a -DELETE checkbox to each
form; you can use jQuery to hide
this, and instead render a delete
button. When clicked, the button
sets the value of the checkbox, and
Django handles the rest. You can see
an example of this here
The ordering can be handled using
a toolkit like jQuery UI -- take a look at this
snippet for ideas. Again,
progressive enhancement is what
you're after here; all your script would
do is update the order field, and let
Django handle the actual saving when you submit.
That way, the functionality is still present, even
if Javascript is disabled (or
absent) on the client

Don't be afraid to explore and experiment. Not all of Django is documented, yet (use the source, Luke :) If you're worried about depending on a feature that might be removed sometime in the future, you can always ask on Django Users

