Nested formsets at Django 1.3

170 views
Skip to first unread message

Kev Dwyer

unread,
Jul 30, 2011, 2:14:43 PM7/30/11
to django...@googlegroups.com
Hello List,

I've been upgrading an old Django 1.1.x app to use Django 1.3, and am
having a problem with nested formsets.

The structure of my formsets is based on the structure outline in
Nathan Yerger's blog post http://yergler.net/blog/2009/09/27/nested-
formsets-with-django/, i.e. I have a grandparent object with a one to
many relation to its child objects, and each of these child objects has
a one to many relation to its children.

This worked fine in Django 1.1.x, but at 1.3 the forms in the lowest
layer always have is_bound = False, even after being rendered and
POSTed back to the view. Consequently validation always fails and the
objects that the forms represent cannot be updated. I've reproduced
the behaviour using the code from Nathan's blog post, so it seems that
this approach to nesting formsets is no longer valid, or the code needs
a tweak to work at 1.3.

Has anyone successfully used Nathan's code at 1.3, or is anyone able to
point me towards a nested formset implementation that works at this
release?

(Sorry about the absence of code examples - Nathan's post is much
clearer than my code, so I'd recommend you look at that.)

Cheers,

Kev

Kev Dwyer

unread,
Jul 31, 2011, 2:52:30 PM7/31/11
to django...@googlegroups.com
Kev Dwyer wrote:

> Hello List,
>
> I've been upgrading an old Django 1.1.x app to use Django 1.3, and am
> having a problem with nested formsets.
>

...
>
>
>
I omitted one important fact in this write-up. In Nathan's original code,
the lowest level formset is created like this:

TenantFormset(data=self.data,
instance=instance,
prefix='TENANTS_%s' % pk_value)

where instance is an instance of Building, the "parent" or container
for tenants and self is an instance of

class BaseBuildingFormset(BaseInlineFormSet)

which is instantiated like this:

BuildingFormset = inlineformset_factory(models.Block,
models.Building,
formset=BaseBuildingFormset,
extra=1)

I omitted to mention that to get around this I stopped passing in self.data,
which led to the behaviour that I described in my original post. Apologies
if this misled anyone.

Up to Django 1.2.5, Nathan's code works fine. However at 1.3, if self.data
is passed to TenantFormset, it turns out to be empty and a ValidationError
is raised because the ManagementForm information has not been supplied.
This is the intended consequewnce of #11418, AFAICT.

Working on the assumption that self.data should contain the
ManagementForm data I've tried populating it with said data, but
ValidationError is still raised.

My use case is slightly simpler than Nathan's example as I just need to edit
existing objects, so I'm going to try populating the formsets using
querysets rather than instances.

Does anyone have any other ideas on how this might be made to work?

Cheers,

Kev

Ilya

unread,
Nov 8, 2011, 12:02:43 PM11/8/11
to django...@googlegroups.com, kevin....@gmail.com
The validation error happens when the formset is passed an empty dictionary. The docs (release notes for 1.3) suggest passing None instead. So doing this should fix the problem:

TenantFormset(data=self.data or None, instance=instance, prefix='TENANTS_%s' % pk_value)

In my case, which is similar to Nathan's, this made the validation error to go away.
Reply all
Reply to author
Forward
0 new messages