'How to use model form instances of a formset in Django template

I'm trying to access the instance of the forms in a formset, but it is not working. I CAN access them using the variable notation, as in {{ form }}, but not in code, as in {% url 'section' form.instance.pk %}. I need to iterate through the forms in the formset along with the corresponding model instance.

My view:

# views.py

def sec(request, companyurl):
    company = get_if_exists(Company, author=request.user)

    SectionFormSet = modelformset_factory(Section, form=SectionForm, can_delete=True)
    sections = Section.objects.filter(company=company).order_by('order')
    formset = SectionFormSet(request.POST or None,
                             initial=[{'company': company}],
                             queryset=sections

    context = {
        'sections': sections,
        'formset': formset,
    }
    return render(request, 'questions/sections.html', context)

My model:

# models.py

class Section(models.Model):

    section = models.CharField(max_length=100)
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    order = models.PositiveIntegerField(default=1000000)
    show = models.BooleanField(default=True)

    def __str__(self):
        return self.section

My Form (I'm using django-crispy forms):

# forms.py
class SectionForm(forms.ModelForm):
    class Meta:
        model = Section
        fields = ['company', 'section', 'show', 'order']
        labels = {
            'section': '',
            'show': 'Show'
        }
    def __init__(self, *args, **kwargs):
        super(SectionForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Div(
                Div(HTML("##"), css_class = 'my-handle col-auto'),
                Div('section', css_class='col-3'),
                Div('show', css_class = 'col-auto'),
                Div('DELETE', css_class = 'col-auto'),
                Field('company', type='hidden'),
                Field('order', type='hidden'),
                css_class='row',
            ),
        )

My template (this is where the problem is seen):

<form action="#" method="post">
  {% csrf_token %}

  {{ formset.management_form }}

  <div id="simpleList" class="list-group">


  {% for fo in formset %}

    <div class="list-group-item hold">

      {% crispy fo %}

      <!-- TESTING TO SEE IF THIS WORKS, AND IT DOES! -->
      {{ fo.instance }} + {{ fo.instance.pk }} + {{ fo.instance.section }}

      <!-- THE PROBLEM OCCURS WHEN THIS IS ADDED -->
      <a href="{% url 'section' fo.instance.pk fo.instance.section %}">
        {{ fo.instance }}
      </a>
      <!-------------------------------------------->

      <input type="hidden" name="order" value="{{ section.pk }}">

      {% for hid in fo.hidden_fields %}
        {{ hid }}
      {% endfor %}

    </div>

  {% endfor %}

  <button type="submit" class="btn btn-outline-primary">Save changes</button>

</form>

When I add the <a href="{% url 'section' fo.instance.pk fo.instance.section %}>link</a> line I get

Reverse for 'section' with arguments '(None, '')' not found. 1 pattern(s) tried: ['section/(?P<pk>[0-9]+)/(?P<section>[^/]+)\\Z']

The error is clear. fo.instance.pk is None and fo.instance.section is an empty string. Yet when I remove the anchor tag, the line above appears and shows the correct values for both of these. I think I know the difference in how the {{ }} and the {% %}, and I thought I knew how model form instances were tied to the model, but I am missing something.

Thanks for any help.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source