Search code examples
djangodjango-formsdjango-widget

How to set modelformset widget.label with value of other model field?


I have a modelformset for a PersonTag model with 3 fields, and I want to display a checkbox widget for the PersonTag.enabled field, and no widget for the other two fields. For each checkbox, I want the label to be set to the PersonTag.tag value for that model instance. How might I accomplish this?

models.py:

from django.db import models

class Person(models.Model):
    name_person = models.TextField()
    tags = models.ManyToManyField('Tag', through='PersonTag')

class Tag(models.Model):
    name_tag = models.TextField()
    persons_tagged = models.ManyToManyField('Person', through='PersonTag')

class PersonTag(models.Model):
    person = models.ForeignKey('Person')
    tag = models.ForeignKey('Tag')
    enabled = models.BooleanField(default=False)

views.py:

from django.forms.widgets import HiddenInput
from django.forms.models import modelformset_factory
from django.shortcuts import render

from models import Person, PersonTag, Tag

def home(request):
    # Should I use a HiddenInput here for 'tag', or is it not necessary?
    ModelFormset_PersonTag = modelformset_factory(model=PersonTag,
                                                  extra=0,
                                                  fields=('enabled','tag',),
                                                  widgets=dict(tag=HiddenInput()))
    # Arbitrarily choose a person for this example
    person = Person.objects.all()[0]
    if request.method == 'GET':
        modelformset_persontag = ModelFormset_PersonTag(
                            queryset=PersonTag.objects.filter(person=person))
        for form in modelformset_persontag.forms:
            # How to reference the .tag.label value here?
            form.fields['enabled'].label = form.fields['tag'].widget.???
        return render(request=request,
                      template_name='home.html',
                      dictionary=dict(
                                modelformset_persontag=modelformset_persontag))

home.html:

<html>
  <body>
    <form method="post" action="">  {% csrf_token %}
        {{ modelformset_persontag.management_form }}

        {% for form_persontag in modelformset_persontag %}
            {{ form_persontag }}
        {% endfor %}

        <input type="submit" value="Submit" />
    </form>
  </body>
</html>

Solution

  • I found a solution that I like:

    form.fields['enabled'].label = form.instance.tag.name_tag
    



    The PersonTag.tag field with a HiddenValue widget is not needed (though it could be used if desired):

    ModelFormset_PersonTag = modelformset_factory(model=PersonTag,
                                                  extra=0,
                                                  fields=('enabled',))
    

    Though no longer needed, I am curious how the value from form.fields['tag'].widget.??? could be obtained.