Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display additional data while iterating over a Django formset

I have a list of soccer matches for which I'd like to display forms. The list comes from a remote source.

matches = ["A vs. B", "C vs. D", "E vs, F"]
matchFormset = formset_factory(MatchForm,extra=len(matches))
formset = MatchFormset()

On the template side, I would like to display the formset with the according title (i.e. "A vs. B").

{% for form in formset.forms %}
    <fieldset>
        <legend>{{TITLE}}</legend>
        {{form.team1}} : {{form.team2}}
    </fieldset>
{% endfor %}

Now how do I get TITLE to contain the right title for the current form? Or asked in a different way: how do I iterate over matches with the same index as the iteration over formset.forms?

Thanks for your input!

like image 428
jnns Avatar asked Feb 27 '23 21:02

jnns


2 Answers

I believe that in the Django template language there is no built-in filter for indexing, but there is one for slicing (slice) -- and therefore I think that, in a pinch, you could use a 1-item slice (with forloop.counter0:forloop.counter) and .first on it to extract the value you want.

Of course it would be easier to do it with some cooperation from the Python side -- you could just have a context variable forms_and_matches set to zip(formset.forms, matches) in the Python code, and, in the template, {% for form, match in forms_and_matches %} to get at both items simply and readably (assuming Django 1.0 or better throughout this answer, of course).

like image 191
Alex Martelli Avatar answered Apr 06 '23 22:04

Alex Martelli


This is an addition to Alex's answer.

I did some reading after my comment on Alex's answer and found that it is important to get the management form (basically a meta-form with information about how many forms are in the formset) into your template for your submitted data to be treated as a formset rather than just a pile of forms. Documentation here.

The only two ways I know to get that into your template are:

  1. Send the formset in addition to whatever data structure you made, and then render the management form with {{ my_formset.management_form }}
  2. Render the management form in your view and send that as an item to your template

Of course if you use Alex's first method, the formset is already available so you can add the management form directly.

like image 29
KobeJohn Avatar answered Apr 07 '23 00:04

KobeJohn