On Tue, 2009-03-03 at 22:42 -0800, Margie wrote:
> Hi Malcolm - Sorry, another formset question.  Maybe you'll know the
> answer offhand, have been trying to figure this out for awhile now.
> I'm trying to set the initial value for a form field inside the
> constructor for the form.  The high level goal is to send out the
> 'tile' field as a hidden input so that I can get it back in the POST
> so that I can figure out wich 'tile' each form in the forset
> corresonds to.
> 
> For example, I'm trying to do this in my form constructor
> (specifically see the ==> line)
> 
> class TaskTileDetailForm(forms.ModelForm):
>     class Meta:
>         model=TaskTileDetail
>         exclude=('task')

If this is a cut-and-paste, this line is almost certainly a bug. The
"exclude" parameter should be a tuple or a list, so ("task",) or
["task"] (note the trailing comma in the tuple case).

> 
>     def __init__(self, tile, *args, **kwargs):

This line is a probably going to be a problem at some point. You cannot
just add new positional arguments into the front of the __init__ call
like this. When Django calls the constructor, it could well be passing
the "data" parameter as the first argument.

Instead, pass it in as a keyword argument. To wit:

        def __init__(self, *args, **kwargs):
           tile = kwargs.pop("tile")
           super(TaskTileDetailForm, self).__init__(*args, **kwargs)
           ...
        
That preserves the ordering of positional arguments.

>         super(TaskTileDetailForm, self).__init__(*args, **kwargs)
>         self.fields['tile'].widget = forms.HiddenInput()
> ==>     self.fields['tile'].initial = tile.id
> 
> If I do this, then later when processing my POST data there is no
> 'tile' key in cleaned_data.  IE, I get a KeyError when I do this:
>     if taskTileDetailForm.cleaned_data["tile"] in taskTiles:
> 
> If I intiaizize it with the initial arg when creating the formset, the
> cleaned_data["tile"] key is set just fine, ie when I use initial as
> shown at the ==> below:

It seems like the problem is how is "tile" meant to be known to each
form? When a formset is constructed, it just constructs and essentially
normal form, passing in any "data" and "initial" parameters. If you need
to do any extra setup on the form -- particularly dealing with passing
in extra parameters -- then you have to do something similar to what I
did in my blog post ([1], for those who don't know what we're talking
about).

So, either, pass in "initial" to the formset, or override the
_construct_form() method, as in the blog post. That's precisely why I
had to do it that way in my example: I needed to pass in some custom
information to each form as it was constructed as part of the formset.

The difference between your case and mine, is that your extra data
corresponds directly to a form field (in mine, the question text was
auxiliary data that wasn't a form field). So I would probably set it up
using the "initial" parameter, if it was me. It would involve far less
formset base class customisation.

[1]
http://www.pointy-stick.com/blog/2009/01/23/advanced-formset-usage-django/


> def makeTaskTileDetailFormSetForCreate(tileList, data=None):
>         TaskTileDetailFormSet = formset_factory
> (form=TaskTileDetailForm, formset=CustomBaseFormSe)
> 
>         initial = []
>         for tile in tileList:
>             initial.append({'tile': tile.id})

Since this is a read-only attribute, you could probably just write

        initial = [{"tile": tile.id}] * len(tileList)
        
That will make each element of initial a reference to the same
dictionary, but that's not a problem since the initial data is only
read, never changed.

Regards,
Malcolm


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

Reply via email to