Inline Formsets Again

View: New views
3 Messages — Rating Filter:   Alert me  

Inline Formsets Again

by John Debs :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I realize the voting for 1.2 features has passed and that the collective attention will be focused on that list, but I'm hoping to get a core developer interested enough to look at potential implementations for this and suggest improvements. The thread I'm resurrecting is this one: http://groups.google.com/group/django-developers/browse_thread/thread/f9aae709a7fda689.

Without further ado:

On Aug 20, 9:01 am, Russell Keith-Magee <freakboy3...@...>
wrote:
> On Sun, Aug 16, 2009 at 5:45 AM, mrts<mrts.py...@...> wrote:
>
> > At HTML level, a form is a set of fields that gets submitted when
> > a the form submit button is pressed.
>
> > However, this is not the case with model forms and inline formsets
> > (e.g. an admin page with inlines) -- inline formsets are
> > disparate from the model form.
>
> > This creates at least two problems:
> > 1) it's impossible to display inline formsets in between ordinary
> > form fields (although they may logically belong to a particular
> > fieldset and not to the end of the form),
>
> This is only true if you consider {{ form }} to be the only way to
> render a form. Remember - you can modify your template to render
> individual fields on a form. If you're looking for sophisticated
> layout options, you should be looking at customizing your template,
> not trying to turn Django's Form.as_ul into the One True Form
> Rendering Tool (tm).
 
I don't buy this. IMO, the real problem with keeping formsets and
forms separate is that developers really should handle forms with
inlines as a single unit, but can't. Consider the example of a
Business model that may have multiple PhoneNumbers, EmailAddresses,
etc:

class Business(models.Model):
   owner = models.ForeignKey(User)
   name = models.CharField(max_length=50)
   address = models.CharField(max_length=100)

class EmailAddress(models.Model):
   email = models.EmailField()
   details = models.CharField(max_length=50)
   business = models.ForeignKey(Business)

class PhoneNumber(models.Model):
   number = PhoneNumberField()
   details = models.CharField(max_length=50)
   business = models.ForeignKey(Business)

In order to present this, I have to create, initialize, pass, and
display a BusinessForm - which Django makes very easy on its own. I
have to do the same with the formsets for EmailAddress and PhoneNumber
- not as easy. As if it weren't bad enough to handle them separately,
they also need to handled /differently/. My nice, encapsulated, atomic
form has been shattered into three parts and my URLConf, views, and
templates all have to deal with that now.

While {{ form }} should obviously not be the only way to render a
form, it should _always_ be an option. It doesn't stop anyone from
customizing templates for more sophisticated layouts. Getting the
example I gave up and running requires entirely customized views (or
separate pages) and far too deep an understanding of Django to be
possible for beginners. And it's annoying for everyone else.

> > 2) it's impossible to create nested (recursive) inlines.
>
> This is true, but not necessarily a bad thing. I'm willing to be
> convinced otherwise, but I'm yet to see a case where nested inlines
> would yield a positive user experience. Forms inside forms inside
> forms is a recipe for  UI disaster.
 
In my experience this is a /very/ common use case - which is even used
in Django admin itself - that's being overlooked. If some developers
want to create awful UIs who are we to stop them? Other devs trying to
quickly prototype code or who just don't need prettier layouts hit
major roadblocks here. Django should easily handle the common cases,
not try to enforce good web design.

I've written a creaky hack to work around the issue in my own projects
but after seeing this thread I'm going to take a shot at implementing
FormSetField (or something like it) myself. If anyone has any code -
or more arguments for or against that haven't been covered - I'd love
to hear them before diving in.

John Debs

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django developers" group.
To post to this group, send email to django-developers@...
To unsubscribe from this group, send email to django-developers+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Inline Formsets Again

by tmcnulty1982 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

We regularly handle a several forms/formsets in a view and it is not a big deal.  For a client with complex search needs, we wrote a few views that manage about 18 different forms each through a python dictionary, e.g.:

forms = {
    'group_name': [Form1(request.POST), Form2(request.POST)],
}

so in your template you can do:

{% for form in forms.group_name %}
    {{ form }}
{% endfor %}

I'm sure there are other ways to do this (perhaps a helper class that handled things like construction and validation for you), but this seemed simple enough to us.

If you really need to stick something between two fields in a form, you can do what Russell said and print out the fields manually, or, if your form is getting too big anyways, break it up into smaller forms and pass them into the template as a list or a dict.

Tobias

On Wed, Oct 28, 2009 at 3:43 AM, John Debs <johnthedebs@...> wrote:
I realize the voting for 1.2 features has passed and that the collective attention will be focused on that list, but I'm hoping to get a core developer interested enough to look at potential implementations for this and suggest improvements. The thread I'm resurrecting is this one: http://groups.google.com/group/django-developers/browse_thread/thread/f9aae709a7fda689.

Without further ado:

On Aug 20, 9:01 am, Russell Keith-Magee <freakboy3...@...>
wrote:
> On Sun, Aug 16, 2009 at 5:45 AM, mrts<mrts.py...@...> wrote:
>
> > At HTML level, a form is a set of fields that gets submitted when
> > a the form submit button is pressed.
>
> > However, this is not the case with model forms and inline formsets
> > (e.g. an admin page with inlines) -- inline formsets are
> > disparate from the model form.
>
> > This creates at least two problems:
> > 1) it's impossible to display inline formsets in between ordinary
> > form fields (although they may logically belong to a particular
> > fieldset and not to the end of the form),
>
> This is only true if you consider {{ form }} to be the only way to
> render a form. Remember - you can modify your template to render
> individual fields on a form. If you're looking for sophisticated
> layout options, you should be looking at customizing your template,
> not trying to turn Django's Form.as_ul into the One True Form
> Rendering Tool (tm).
 
I don't buy this. IMO, the real problem with keeping formsets and
forms separate is that developers really should handle forms with
inlines as a single unit, but can't. Consider the example of a
Business model that may have multiple PhoneNumbers, EmailAddresses,
etc:

class Business(models.Model):
   owner = models.ForeignKey(User)
   name = models.CharField(max_length=50)
   address = models.CharField(max_length=100)

class EmailAddress(models.Model):
   email = models.EmailField()
   details = models.CharField(max_length=50)
   business = models.ForeignKey(Business)

class PhoneNumber(models.Model):
   number = PhoneNumberField()
   details = models.CharField(max_length=50)
   business = models.ForeignKey(Business)

In order to present this, I have to create, initialize, pass, and
display a BusinessForm - which Django makes very easy on its own. I
have to do the same with the formsets for EmailAddress and PhoneNumber
- not as easy. As if it weren't bad enough to handle them separately,
they also need to handled /differently/. My nice, encapsulated, atomic
form has been shattered into three parts and my URLConf, views, and
templates all have to deal with that now.

While {{ form }} should obviously not be the only way to render a
form, it should _always_ be an option. It doesn't stop anyone from
customizing templates for more sophisticated layouts. Getting the
example I gave up and running requires entirely customized views (or
separate pages) and far too deep an understanding of Django to be
possible for beginners. And it's annoying for everyone else.

> > 2) it's impossible to create nested (recursive) inlines.
>
> This is true, but not necessarily a bad thing. I'm willing to be
> convinced otherwise, but I'm yet to see a case where nested inlines
> would yield a positive user experience. Forms inside forms inside
> forms is a recipe for  UI disaster.
 
In my experience this is a /very/ common use case - which is even used
in Django admin itself - that's being overlooked. If some developers
want to create awful UIs who are we to stop them? Other devs trying to
quickly prototype code or who just don't need prettier layouts hit
major roadblocks here. Django should easily handle the common cases,
not try to enforce good web design.

I've written a creaky hack to work around the issue in my own projects
but after seeing this thread I'm going to take a shot at implementing
FormSetField (or something like it) myself. If anyone has any code -
or more arguments for or against that haven't been covered - I'd love
to hear them before diving in.

John Debs





--
Tobias McNulty
Caktus Consulting Group, LLC
P.O. Box 1454
Carrboro, NC 27510
(919) 951-0052
http://www.caktusgroup.com

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django developers" group.
To post to this group, send email to django-developers@...
To unsubscribe from this group, send email to django-developers+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Inline Formsets Again

by mrts-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Oct 28, 9:43 am, John Debs <johnthed...@...> wrote:
> I've written a creaky hack to work around the issue in my own projects
> but after seeing this thread I'm going to take a shot at implementing
> FormSetField (or something like it) myself. If anyone has any code -
> or more arguments for or against that haven't been covered - I'd love
> to hear them before diving in.

I have to admit that I haven't got time for working on this right now,
but I'd be most willing to collaborate - e.g. review code. Perhaps we
should continue off-list - as this hasn't been officially accepted -
until
we've fleshed out a proper proposal and some code.

Best,
Mart Sõmermaa
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django developers" group.
To post to this group, send email to django-developers@...
To unsubscribe from this group, send email to django-developers+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---