Issue
I'm trying to display and use a form that uses a manytomany field, widgetized as checkboxes
The problem I'm having is when I view the page, the state of the checkboxes isn't visible (all the checkboxes show as unchecked, but there are related rows in the database for the manytomany relations). What I'd like to do is display an "edit" form with all the correct statuses for the checkboxes (i.e. checked checkboxes for existing manytomany values in the database, unchecked checkboxes for missing values)
here's the form declaration:
class EditPatientForm(forms.ModelForm):
flags = forms.ModelMultipleChoiceField(
queryset=PatientFlag.objects.filter(visible_on_edit=True),
widget=forms.CheckboxSelectMultiple,
required=False)
class Meta:
model = Patient
exclude = ('profile_picture','registered_on')
fields = "__all__"
helper = FormHelper()
Every "patient" has some associated "flags" such as "has diabetes" or "has heart problems". I want to display a form with a list of checkboxes so the user can select "has diabetes" as a checkbox, which then gets saved in the database.
Here are the two models:
class PatientFlag(models.Model):
name = models.CharField(max_length=255, null=True)
question = models.CharField(max_length=255, null=True)
description = models.TextField(null=True)
visible_on_create = models.BooleanField( default=True)
visible_on_edit = models.BooleanField(default=True)
class Patient(models.Model):
"""Represents a patient"""
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
flags = models.ManyToManyField(PatientFlag, db_index=True, related_name='patient')
Now, when I go and edit the patient using this form, I get a list of all the checkboxes representing "flags", but they are all always unchecked
How can I fix this?
Solution
to make sure that the checkboxes in your EditPatientForm
are pre-selected based on the existing flags
associated with a patient you need to pass the instance of the patient to the form when you instantiate it. assuming you are using django's generic UpdateView
you can modify your view like this:
from django.views.generic.edit import UpdateView
from .models import Patient
from .forms import EditPatientForm
class EditPatientView(UpdateView):
model = Patient
form_class = EditPatientForm
template_name = 'your_template.html'
def get_form(self, form_class=None):
form = super(EditPatientView, self).get_form(form_class)
form.helper = FormHelper()
return form
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'].instance = self.object # you pass the instance to the form
return context
remember to replace your_template.html
with the path to your template
now when the EditPatientForm
is rendered it will take into account the existing flags
associated with the patient instance and per-select the checkboxes accordingly
if you are not using django's generic views make sure you pass the instance when creating the form in your view like this:
def edit_patient_view(request, patient_id):
patient = get_object_or_404(Patient, pk=patient_id)
if request.method == 'POST':
form = EditPatientForm(request.POST, instance=patient)
if form.is_valid():
form.save()
# you cand redirect or do something after successful form submission
else:
form = EditPatientForm(instance=patient)
return render(request, 'your_template.html', {'form': form, 'patient': patient})
I hope this helps you.
Answered By - Kiarash Gh
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.