访问 CheckboxSelectMultiple 复选框的属性
Posted
技术标签:
【中文标题】访问 CheckboxSelectMultiple 复选框的属性【英文标题】:Accessing Attributes of a CheckboxSelectMultiple checkbox 【发布时间】:2019-02-22 19:31:03 【问题描述】:短版
在 Django 模板语言中,如何访问 CheckboxSelectMultiple
小部件中给定复选框的属性?
加长版
可以轻松访问典型 Django 小部件的属性:
% for field in form %
field.widget.attrs.something
% endfor %
但是,此方法不适用于CheckboxSelectMultiple
小部件内的复选框。
我有一个自定义的 CheckboxSelectMultiple
小部件,我用它来显示 ManyToMany
ModelForm
字段。自定义小部件为 create_option
方法中的每个复选框添加了额外的属性。
附加属性在输入元素的 html 中适当显示:
<input type="checkbox" name="questions" value="22" id="id_questions_12" category="Category Name" category_number="3" question="Question Name" question_number="4">
为了显示和组织表单字段,我需要访问这些附加属性。
【问题讨论】:
【参考方案1】:在放置一周左右后,我又回到了这个问题。在玩了更多并阅读了BoundField(特别是BoundWidget
)的文档之后,我发现了如何访问CheckboxSelectMultiple
小部件中单个复选框的attrs
:
% for field in form %
% for check in field.subwidgets %
% for a in check.data.attrs %
【讨论】:
【参考方案2】:我能够使用this answer 中给出的相同技术。它非常适用于CheckboxSelectMultiple
,尽管它没有在答案中使用。
我把它保存在我项目的forms.py
:
from django.forms.widgets import CheckboxSelectMultiple, Select
class SelectWithAttrs(Select):
"""
Select With Option Attributes:
Subclass of Django's Select widget that allows attributes in options,
e.g. disabled="disabled", title="help text", class="some classes",
style="background: color;", etc.
Pass a dict instead of a string for its label:
choices = [ ('value_1', 'label_1'),
...
('value_k', 'label': 'label_k', 'foo': 'bar', ...),
... ]
The option k will be rendered as:
<option value="value_k" foo="bar" ...>label_k</option>
"""
def create_option(self, name, value, label, selected, index,
subindex=None, attrs=None):
if isinstance(label, dict):
opt_attrs = label.copy()
label = opt_attrs.pop('label')
else:
opt_attrs =
option_dict = super().create_option(
name, value, label, selected, index,
subindex=subindex, attrs=attrs)
for key, val in opt_attrs.items():
option_dict['attrs'][key] = val
return option_dict
class CheckboxSelectMultipleWithAttrs(
SelectWithAttrs, CheckboxSelectMultiple):
pass
这是我的一个项目中使用此示例的工作 sn-p。一开始的内容并不重要,但它展示了如何构建您的属性字典并将其传递给您的choices
。
from django import forms
from django.whatever import other_stuff
from project_folder import forms as project_forms
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['employees']
def __init__(self, *args, **kwargs)
super().__init__(*args, **kwargs)
self.fields['employees'].queryset =\
self.company.employee_set.filter(is_active=True)
existing_crews_employees = []
for crew in existing_job_crews:
crew_employees =\
[employee.__str__() for employee in crew.employees.all()]
existing_crews_employees.append('crew_name': crew.crewtype.name,
'employees': crew_employees)
employees_choices = []
for (index, choice) in enumerate(self.fields['employees'].choices):
# loop over each choice and set proper paramaters for employees
# that are unassigned/on the current crew/on a different crew
employee_in_crew = False
employee_name = choice[1]
for crew_and_employees in existing_crews_employees:
for employee in crew_and_employees['employees']:
if employee_name == employee.__str__():
crew_name = crew_and_employees['crew_name']
if self.obj and self.obj.crewtype.name == crew_name:
# check the box if employee in current crew
employees_choices.append((choice[0],
'label': choice[1],
'checked': True,
'id': f'id_employees_choice[0].instance.id'
))
else:
# disable the choice if employee in another crew
employees_choices.append((choice[0],
'label':
employee_name + f" (on Crew: crew_name)",
'disabled': True))
employee_in_crew = True
# for valid entries, ensure that we pass the proper ID
# so that clicking the label will also check the box
if not employee_in_crew:
employees_choices.append((choice[0],
'label': choice[1],
'id': f'id_employees_choice[0].instance.id'))
self.fields['employees'].widget = project_forms.CheckboxSelectMultipleWithAttrs(
choices=employees_choices)
在使用此技术时要牢记两件重要的事情:
确保将id
传递到您的 attrs 以获得可点击选项,否则您的标签在被点击时不会选中正确的框。
此方法当前需要使用新属性 dict 设置初始值。确保将 'checked': True
键值对传递给任何应选中的框。
【讨论】:
以上是关于访问 CheckboxSelectMultiple 复选框的属性的主要内容,如果未能解决你的问题,请参考以下文章
Django Admin Template Overriding:显示 checkboxselectmultiple 小部件
Wagtail admin,CheckboxSelectMultiple不保存数据
Django CheckboxSelectMultiple 覆盖 ModelForm 中的“选择”
如何在不覆盖 ModelForm 中的字段定义的情况下将 ManyToManyField 小部件更改为 CheckboxSelectMultiple
Django Modelmultiplechoicefield Checkboxselectmultiple 获取选中复选框的问题