首页 > 解决方案 > django checkboxSelectMultiple

问题描述

发生了一些非常奇怪的事情,我在 forms.py 中构建了一个 MultipleChoiceField ,它呈现为一个普通列表。我无法显示复选框。我希望有人能发现我可能出错的地方。

表格.py

from django import forms
from . import models
from behaviour.models import Interventions

class IncidentForm(forms.Form):

    def __init__(self,*args,**kwargs):
        self.request = kwargs.pop('request')
        super(IncidentForm,self).__init__(*args, **kwargs)

        intervention_set = Interventions.objects.filter(schoolid_id = self.request)
        intervention_choice = []
        for intervention in intervention_set:
            intervention_choice.append((intervention.pk, intervention.name))
        self.fields['intervention'].choices = intervention_choice

    intervention = forms.MultipleChoiceField(label='Intervention', choices=(), widget=forms.CheckboxSelectMultiple(), required=True,)

事件.html

<div>
    <label class="control-label">{% trans 'Intervention' %}</label><br />
    {{ form.intervention }}
    <small class="form-control-feedback"> {{ form.intervention.errors }} </small> 
</div>

HTML 输出

<div>
    <label class="control-label">Intervention</label><br>
    <ul id="id_intervention">
        <li><label for="id_intervention_0"><input type="checkbox" name="intervention" value="3" id="id_intervention_0">
        Communicate verbally with Parent</label>
        </li>
        <li><label for="id_intervention_1"><input type="checkbox" name="intervention" value="2" id="id_intervention_1">
        Non-verbal signal</label>
        </li>
        <li><label for="id_intervention_2"><input type="checkbox" name="intervention" value="1" id="id_intervention_2">
        Spoke with Student</label>
        </li>
    </ul>
    <small class="form-control-feedback">  </small> 
</div>

输出截图

标签: django-formsdjango-templates

解决方案


如果您使用 Django admin 并且您的父模型没有使用与子模型的任何关系,但具有 charfield 来存储将作为自定义字段添加到 ModelAdmin 的子模型的选定项目的 id。

遵循步骤: 第 1 步:model.py

   class yourparentmodel(models.Model):
        ...
    prior_learning_checks = models.CharField(max_length=120, null = True, blank=True)
        ...

class childmodel(models.Model):
   rpl_id = models.CharField(max_length=4, null = True, blank=True)
   rpl_desc = models.CharField(max_length=120, null = True, blank=True)

在此示例中,父级是 CohortDetails 作为 Cohort 的内联,或者仅在不需要内联时才可以限制为 Cohort。

在这个例子中,子模型是 StudentRPL。

第 2 步:admin.py 添加 CheckboxSelectMultiple 以列出此示例中的 id 和描述的表数据。然后使用init为带有父表单的子模型附加您的自定义字段。

class StudentRPLForm(forms.ModelForm):

    student_prior_learning = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=StudentRpl.objects.all())

    class Meta:
        model = StudentRpl
        fields = [
                'rpl_indicator',
                'rpl_description',
               ]



 def __init__(self, *args, **kwargs):
            
            super(StudentRPLForm, self).__init__(*args, **kwargs)
    
            if self.instance and self.instance.pk:
                    self.fields['student_prior_learning']=forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=StudentRpl.objects.all())
                
                rpl_list = []
    
                ids = self.instance.prior_learning_checks
    
                if ',' in ids:
                    ids = ids[0:(len(ids) - 1)]
                    rpl_list = ids.rsplit(',')
                    self.fields['student_prior_learning'].initial = StudentRpl.objects.filter(rpl_indicator__in=rpl_list)

现在是时候通过覆盖 save(self, commit) 来保存数据了。 确保使用cleaned_data。仅收集检查的行数据并保存到父模型的字符字段以在加载 change_form 时再次读取它是很神奇的。因为您保存为逗号分隔的 id,所以您有机会将此字符串加载到列表中并过滤您的自定义子模型。通过在上面的init函数中为您的过滤数据分配 self.fields['student_prior_learning'].initial 值(就像我所做的那样),以逗号查看最后保存的 id 的其他魔法!

   def save(self, commit=True, *args, **kwargs):
       m = super(StudentRPLForm, self).save(commit=False, *args, **kwargs)

       selected_rpl_list = ''
       if self is not 'CohortDetailsForm':
            for cr in self.cleaned_data['student_prior_learning']:
            
                selected_rpl_list += cr.rpl_indicator + ','

        m.prior_learning_checks = selected_rpl_list

        if commit:
            m.save()

第 3 步:admin.py 将表单分配给 Inline 或直接分配给 modeladmin 类(如果您不需要内联)。

class CohortDetailInline(admin.StackedInline):
    model = CohortDetails
    form = StudentRPLForm
    fieldsets = ['fields':, ('student_prior_learning')]
    .....


@admin.register(Cohort)
class CohortAdmin(admin.ModelAdmin):
      inlines = CohortDetailInline
      ....

完毕 !!!!


推荐阅读