'Django Forms - How would I implement a form that dynamically changes its fields depending on model objects in the database?
I have 3 models :
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
class Certification(models.Model):
def __str__(self):
return f'{self.name}'
name = models.CharField(max_length=30)
shortName = models.CharField(max_length=10)
score = models.IntegerField(null=True, blank=True)
class ActiveCertification(models.Model):
def __str__(self):
return f'{self.user} | {self.sensor}'
user = models.ForeignKey(User, on_delete=models.CASCADE)
certification = models.ForeignKey(Certification, on_delete=models.CASCADE)
value = models.BooleanField()
In my database, there are a few different Certification objects, but there is bound to be more in the future.
My ActiveCertification model is used to identify which user has which certification.
Now, the problem I am facing is that I wish that each user could fill out which certifications they have in a form. I basically need the form to look like this :
Certification 1 [ ]
Certification 2 [ ]
Certification 3 [ ]
Certification 4 [ ]
ect...
[ Submit ]
([ ] representing a checkbox)
Basically, I need that when user A uses this form, he checks the certifications he has, and that upon submitting, the ActiveCertification table would fill/update the userA/certification pairs.
At first, I started doing a form like this :
from django import forms
class ActiveCertificationForm(forms.Form):
certification1 = forms.BooleanField(required=False)
certification2 = forms.BooleanField(required=False)
certification3 = forms.BooleanField(required=False)
certification4 = forms.BooleanField(required=False)
But quickly realized that this is a terrible solution, as when new certifications would be added to the database, the form wouldn't automatically update.
I tried looking in the Django documentation for help, and tried to implement the form with the ModelChoiceField field, but it doesn't really work, as it produces a dropdown list, and I need a checkbox list.
Any help would be greatly appreciated. Thanks in advance !
Solution 1:[1]
There are two possibilities:
model formsets and using a forms.ModelMultipleChoiceField with a CheckBoxSelectMultiple widget.
formsets
forms.py:
from django.forms import modelformset_factory
from yourapp.models import ActiveCertification
ActiveCertificationFormSet = modelformset_factory(ActiveCertification, fields=('certification', 'value',))
views.py
from django.shortcuts import render
from yourapp.forms import ActiveCertificationFormSet
from yourapp.models import ActiveCertification
def your_view(request, *args, **kwargs):
active_certs = ActiveCertivication.objects.filter(user=request.user)
context = {
'certification_formset': ActiveCertificationFormSet(
queryset=active_certs,
),
}
return render(request, 'certification_template.html', context)
ModelMultipleChoiceField
from django import forms
class CertificationForm(forms.Form):
certifications = forms.ModelMultipleChoiceField(
widget=forms.CheckBoxSelectMultiple(),
)
See the respective documentation linked above for more details.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | SMoenig |
