Search code examples
djangoformset

How to utilise ID field as url parameter in formset template code (using django-extra-views)


I'm trying to adopt 'extra-views' as an advanced means of handling formsets, and want to have a link on each row of my formset template to redirect to a relevant object-based page, for which I need the initial value of that object's id field as url parameter.

Here's the view:

from extra_views import ModelFormSetView
from .models import Course

class CourseFormSetView(ModelFormSetView):
    model = Course
    fields = ['id', 'ceName', 'ceExtName', 'ceDuration']
    template_name = 'course_view.html'
    factory_kwargs = {'extra': 1, 'max_num': None, 'can_order': False, 'can_delete': True}

Here's the relevant section of the template:

<form method="post">
    {% csrf_token %} 
    {% for form in formset %}
        <p>{{ form.ceName }} {{ form.ceExtName }} {{ form.DELETE }} <a href="{% url 'booksys:coursesetup_view' 1 %}" class="btn btn-info" role="button">Edit</a></p>
    {% endfor %}
    {{ formset.management_form }}
  <input type="submit" value="Submit" />
</form>

For url parameter, I've tried {{ form.fields.id.value }} but it doesn't render into the template at all, and {{ form.id }} which renders as a hidden field but won't work with the url template directive and the template rendering then fails.

Any help much appreciated.


Solution

  • I worked out the answer to this, and I think it is useful enough to share:

    Since form.id is a hidden field, my template url needs to include form.id.value in order to properly render and bind into the url part of the template.

    With 'extra': 1 in my factory_kwargs, I needed it to read form.id.value|default_if_none:0 and then handle the special case of zero for kwargs['pk'] in the linked view, since otherwise for new formset rows this field reads None.

    The relevant portion of my template now reads:

    <form method="post">
        {% csrf_token %} 
        {% for form in formset %}
            <p>{{ form.ceName }} {{ form.ceExtName }} {{ form.DELETE }} <a href="{% url 'booksys:coursesetup_view' form.id.value|default_if_none:0 %}" class="btn btn-info" role="button">Edit</a></p>
        {% endfor %}
        {{ formset.management_form }}
      <input type="submit" value="Submit" />
    </form>