django-forms - 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 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
....
完毕 !!!!
推荐阅读
- angular - Angular 7 /JS , video.currentTime 在 Google Chrome 上无法正常工作,但在 Firefox 上正常工作
- python - 程序不返回正确答案(计算最小周长)
- amazon-web-services - 在弹性负载均衡器后面混合 EC2 和 Fargate 任务
- json - 无法弄清楚如何通过可编码获取所有新的 json 数据
- arrays - 如何使用冒号运算符将半整数序列压缩为字符串表达式?(如何将列表转换为字符串)
- r - 在经度和纬度上填充渐变
- arrays - 用户定义函数,用于在一个参数中输入多个单元格时返回结果
- xml - XSL - 如何在另一个循环中为每个循环下一个链接来自不同 xml 节点的相同值
- node.js - 在我的 NodeJS 程序中,为什么我的数组没有定义
- c++ - 有条件地包含 C++ 标准库