如何创建一个带有RadioSelect字段的Django表单,并禁用一些按钮?
我正在创建一个带有一组单选按钮(作为单个RadioSelect字段)的Django表单,我希望其中一些按钮变灰。然而,鉴于RadioSelect字段是表单上的单个字段,我还没有找到这样做的方法如何创建一个带有RadioSelect字段的Django表单,并禁用一些按钮?,django,django-models,Django,Django Models,我正在创建一个带有一组单选按钮(作为单个RadioSelect字段)的Django表单,我希望其中一些按钮变灰。然而,鉴于RadioSelect字段是表单上的单个字段,我还没有找到这样做的方法 class OrderStatusForm(forms.Form): os = Order_Status.objects.values_list('id', 'status') status = forms.ChoiceField(choices=os, widget=forms.Radi
class OrderStatusForm(forms.Form):
os = Order_Status.objects.values_list('id', 'status')
status = forms.ChoiceField(choices=os, widget=forms.RadioSelect())
def makeForm():
newForm = OrderStatusForm()
# next line disables all radio buttons.
newForm.fields['status'].widget.attrs['disabled'] = True
有没有办法选择性地禁用单个单选按钮?或者我不必首先将禁用的选项放在列表中?可以尝试:
status = forms.ChoiceField(choices=os, widget=forms.RadioSelect(attrs={'disabled':'disabled'}))
或
您可以使用JavaScript在模板中执行此操作,如下所示:
<script>
$(function() {
{% for val in disable %}
$('input[name="status"][value="{{ val }}"]').attr('disabled', true);
{% endfor %}
});
</script>
$(函数(){
{%用于禁用%中的val}
$('input[name=“status”][value=“{{val}}}”]').attr('disabled',true);
{%endfor%}
});
假设jQuery(用于
$
)和disable
(在{%for%}
循环中)是传递给模板的一个变量,该变量的计算结果是希望变灰的值列表。进一步研究发现,RadioSelect渲染器可以替换,并作为参数传递给初始小部件创建函数。因此,我创建了自己的渲染器,并附加了一个布尔值列表,指示应该禁用哪些单选按钮
渲染器根据需要向每个单选按钮小部件添加禁用属性,然后强制unicode将小部件的属性转换为包含disabled=“True”
值的HTML
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
class RandomRenderer(forms.RadioSelect.renderer):
""" Modifies some of the Radio buttons to be disabled in HTML,
based on an externally-appended Actives list. """
def render(self):
if not hasattr(self, "actives"): # oops, forgot to add an Actives list
return self.original_render()
return self.my_render()
def original_render(self):
return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>'
% force_unicode(w) for w in self]))
def my_render(self):
midList = []
for x, wid in enumerate(self):
if self.actives[x] == False:
wid.attrs['disabled'] = True
midList.append(u'<li>%s</li>' % force_unicode(wid))
finalList = mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>'
% w for w in midList]))
return finalList
class OrderStatusForm(forms.Form):
os = Order_Status.objects.values_list('id', 'status', 'reason')
activeList = [True, False, True, False, True, False,]
newStatus = forms.ChoiceField(widget=forms.RadioSelect(
renderer=RandomRenderer), choices=os)
newStatus.widget.renderer.actives = activeList
来自django.utils.safestring导入标记\u safe
从django.utils.encoding导入强制\u unicode
类RandomRenderer(forms.RadioSelect.renderer):
“”“修改要在HTML中禁用的某些单选按钮,
基于外部附加的活动列表。”“”
def渲染(自):
如果不是hasattr(self,“actives”):#哦,忘了添加一个actives列表
返回self.original_render()
返回self.my_render()
def原始_渲染(自):
返回标记\u safe(u'\n%s\n
'%u'\n'。加入([u'%s '
%强制_unicode(w)表示w(在self中)()
定义我的渲染(自):
中间列表=[]
对于x,枚举中的wid(自):
如果self.actives[x]==False:
wid.attrs['disabled']=True
追加(u'%s '%force\u unicode(wid))
finalList=mark\u safe(u'\n%s\n
'%u'\n'。加入([u'%s '
%w代表中间列表中的w]))
回归终结者
类OrderStatusForm(forms.Form):
os=订单\状态.对象.值\列表('id','Status','reason'))
activeList=[True,False,True,False,True,False,]
newStatus=forms.ChoiceField(widget=forms.RadioSelect(
渲染器=随机渲染器),选项=操作系统)
newStatus.widget.renderer.actives=activeList
这有点麻烦-我只是将actives列表直接粘贴到渲染器上,这很有效(喜欢Python的duck类型),但是如果我在一些构造函数中传递该列表,会更干净。不幸的是,我在这方面遇到了问题,所以选择了简单的方法 这与我发布的内容没有什么不同-状态
被视为一个字段(有多个单选按钮),并且整个内容被禁用。将代码移动到init不会改变它的影响。谢谢,这是一个有趣的方法。我不清楚如何引用每个字段-下标?或者Django是否指定了默认名称?(另外,我将在不使用JS的情况下启动该网站,并最终添加它,因为我确定了最佳使用区域。)“输入[name=“status”]”部分将找到您的所有字段,称为status,就像表单中一样。“[value=“{val}}”]”部分将选择一个特定的单选按钮。与for循环相结合,最终禁用所有必需字段。默认名称是字段“status”的名称。您仍然需要在服务器端检查它,因为有人可以修改HTML。更简单的方法是在调用super方法之前覆盖forms.RadioSelect的create\u选项
方法,并在需要时添加attrs['disabled']=True
。
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
class RandomRenderer(forms.RadioSelect.renderer):
""" Modifies some of the Radio buttons to be disabled in HTML,
based on an externally-appended Actives list. """
def render(self):
if not hasattr(self, "actives"): # oops, forgot to add an Actives list
return self.original_render()
return self.my_render()
def original_render(self):
return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>'
% force_unicode(w) for w in self]))
def my_render(self):
midList = []
for x, wid in enumerate(self):
if self.actives[x] == False:
wid.attrs['disabled'] = True
midList.append(u'<li>%s</li>' % force_unicode(wid))
finalList = mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>'
% w for w in midList]))
return finalList
class OrderStatusForm(forms.Form):
os = Order_Status.objects.values_list('id', 'status', 'reason')
activeList = [True, False, True, False, True, False,]
newStatus = forms.ChoiceField(widget=forms.RadioSelect(
renderer=RandomRenderer), choices=os)
newStatus.widget.renderer.actives = activeList