django checkboxSelectMultiple

Posted

技术标签:

【中文标题】django checkboxSelectMultiple【英文标题】: 【发布时间】:2018-10-18 17:43:28 【问题描述】:

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

forms.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,)

incident.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>

Screenshot of output

【问题讨论】:

尝试从您的小部件中删除choices。或者将选项放在选项中并让它呈现它们。 我想多了。您在 def init 中设置选项,然后在制作小部件时覆盖选项。尝试在您的初始化中进行干预选择,并设置小部件选择 = 干预选择 【参考方案1】:

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

请按以下步骤操作: 第 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 作为内联队列,或者仅在不需要内联时才可以限制为队列。

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

第 2 步:admin.py 添加 CheckboxSelectMultiple 以列出此示例中 id 和 description 的表数据。 然后使用 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,所以您有机会将此字符串加载到列表中并过滤您的自定义子模型。 通过分配以逗号查看上次保存的 id 的其他魔法: self.fields['student_prior_learning'].initial value 为您在上面的 init 函数中过滤的数据(就像我一样)!!!

   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
      ....

完成!!!!

【讨论】:

以上是关于django checkboxSelectMultiple的主要内容,如果未能解决你的问题,请参考以下文章

Django之路

Django系列

django 错误

mac电脑安装django ,运行django报错解决

Django 大神带你飞系列~走进Django

django的文档