Hi all,

using a formset with a large number of forms, I would like to add "extra data" to each of the forms that I can render in the template as read-only info near the fields of the related form.

For example, let's assume we have a formset with one form for each day in the month, and each form has input fields "start time" and "end time" that the user is supposed to enter. When the user edits previously saved data, for each form I would like to print the precomputed duration, end minus start, next to the two input fields (my real computation is more complicated than that so it must run on the server and cannot e.g. be done in JavaScript).

What is the proper way to do that, especially when validating a POST-submitted form fails and the form must be redisplayed?


Allow me to explain this in more detail:

Let's consider each of the three code paths for processing a form as described at <https://docs.djangoproject.com/en/1.3/topics/forms/#using-a-form-in-a-view>:


1. No form(set) has been submitted, and we're creating a new unbound one with initial data, e.g. like this:

        Inits = [ {...}, ... one dict per form with initial data ]
        myFormSet = myFormSetFactory(initial=Inits)

In this case I've successfully used either of two approaches for combining the forms with the extra data for rendering in the template: (However, I believe that both approaches are wrong or at least questionable...)

1a. Create another list of dictionaries like Inits like this:

    Tabelle = [{} for i in Inits]
    FormNr = 0
    for Zeile in Tabelle:
        Zeile['extra'] = per_form_static_info_data[FormNr]
        Zeile['form'] = myFormSet.forms[FormNr]
        FormNr += 1

per_form_static_info_data is a list of the same size as Inits, created at the same time, and contains the expensively computed extra data.

Then we pass Tabelle to the template and loop over it for rendering the forms and the extra data. Given that, myFormSet itself is needed in the template only for the management form and the csrf-token.

1b. Alternatively, add the extra data to the forms instead, like this:

    for Nr, Form in enumerate(myFormSet.forms):
        Form.Extra = per_form_static_info_data[Nr]

In this case, we pass myFormSet to the template where we loop over its forms and take the extra data directly from it.


Both methods work, but both feel wrong to me, and from the Django perspective, I cannot even tell which one is preferable?

Notice that in both cases, when the form is submitted, the extra data is not transferred from the client to the server, because it's just static text that is not part of any input field.


2. When the formset is submitted and valid, the matter is easy: We really should be able to save the submitted data from what we have in the form fields, without any need to bother about the extra stuff at all.


3. The really problematic case that really motivated me to post this question here: The formset was submitted, fails validation, and thus should be redisplayed, both with the error messages *and* - as before - with the extra data.

In this situation, we could regenerate the per_form_static_info_data list and *hope* that the submitted forms and the per_form_static_info_data list are still parallel, and then use one of the methods described in 1a or 1b again to combine them...

But if this felt wrong in step 1., it feels like a receipt to disaster now: During the time that the user took to fill-in the forms, other users may have added/deleted/changed the underlying models totally, so that the list with extra data would be totally out of sync with what arrived in request.POST.

This seems like a type of problem that occurs frequently, but I seemingly cannot see a good solution.

How do you handle it?
Are there any best practices?  (Django-style solutions? ;-) )


Epilogue:

Instead of 1a and 1b, what do you think of putting the extra data into hidden fields instead? (Would this work even if some of the extra data were instances of models.Model?)

The extra data would then be part of the Inits list, and (re-)creating the separate per_form_static_info_data would totally be eliminated.

But in the template, how do I render? If "form" is a form in the formset, {{ form.some_field }} would render the *hidden* field, but I'd *also* need the text string besides it...?


I'd be very grateful for your help, and many thanks if you've read until here!

Thank you very much for your time,
and best regards,
Carsten



--
   Cafu - the open-source Game and Graphics Engine
for multiplayer, cross-platform, real-time 3D Action
          Learn more at http://www.cafu.de

--
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