带有复选框的Django ManytoMany表单:如何保留“选中”和“未选中”值?

问题描述 投票:0回答:1

我正在尝试显示和使用一个使用多域字段的表单,小部件化为复选框

我遇到的问题是,当我查看页面时,复选框的状态不可见(所有复选框都显示为未选中,但数据库中存在多关系的相关行)。 我想要做的是显示一个“编辑”表单,其中包含复选框的所有正确状态(即选中数据库中现有多个值的复选框,未选中缺失值的复选框)

这是表格声明:

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()

每个“患者”都有一些相关的“标志”,例如“患有糖尿病”或“有心脏问题”。我想显示一个带有复选框列表的表单,以便用户可以选择“患有糖尿病”作为复选框,然后将其保存在数据库中。

这是两个型号:

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')

现在,当我使用此表单编辑患者时,我会得到代表“标志”的所有复选框的列表,但它们始终处于未选中状态

我该如何解决这个问题?

python django django-views django-forms
1个回答
0
投票

为了确保根据与患者关联的现有

EditPatientForm
预先选择
flags
中的复选框,您需要在实例化患者时将患者实例传递到表单。假设你正在使用 django 的通用
UpdateView
你可以像这样修改你的视图:

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

记得将

your_template.html
替换为模板的路径 现在,当渲染
EditPatientForm
时,它将考虑与患者实例关联的现有
flags
并相应地选择复选框

如果您不使用 django 的通用视图,请确保在视图中创建表单时传递实例,如下所示:

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})

希望这对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.