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.