如何使用RadioSelect字段创建Django表单,并禁用某些按钮?

时间:2011-08-12 23:18:09

标签: django django-models

我正在创建一个带有一组Radio按钮的Django表单(作为单个RadioSelect字段),我希望某些按钮变灰。但是,鉴于RadioSelect字段是表单上的单个字段,我还没有找到办法。

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

有没有办法有选择地禁用个别单选按钮?或者我是否必须首先将禁用的选项放在列表中?

3 个答案:

答案 0 :(得分:6)

进一步研究发现,RadioSelect renderer可以替换,并作为参数传递给初始小部件创建功能。所以我创建了自己的渲染器,并附上了一个布尔列表,指出应该禁用哪些单选按钮。

渲染器根据需要为每个单选按钮窗口小部件添加禁用属性,然后 force_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

这是一个小小的kludgy - 我只是将 actives 列表直接粘贴到渲染器上,它可以工作(喜欢Python的鸭子打字),但如果我在一些构造函数中传递列表会更清晰。不幸的是我遇到了问题,所以采取了简单的方法。 :)

答案 1 :(得分:1)

也许试试:

status = forms.ChoiceField(choices=os, widget=forms.RadioSelect(attrs={'disabled':'disabled'}))

class OrderStatusForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(OrderStatusForm, self).__init__(*args, **kwargs)
        self.fields['status'].widget.attrs['disabled'] = 'disabled'

    os = Order_Status.objects.values_list('id', 'status')
    status = forms.ChoiceField(choices=os, widget=forms.RadioSelect())

答案 2 :(得分:0)

您可以使用JavaScript在模板中执行此操作:

<script>
  $(function() {
        {% for val in disable %}
        $('input[name="status"][value="{{ val }}"]').attr('disabled', true);
        {% endfor %}
    });
</script>

假设你有jQuery(对于$)和disable(在{% for %}循环中)是一个传递给模板的变量,它会计算到列表你想要变灰的价值。