覆盖表单的__init__并设置禁用的复选框并使用initial = True

时间:2011-08-24 16:19:25

标签: django django-forms

我有一个表单,我将覆盖 init ,因此我可以设置一些禁用的复选框,这些已禁用的复选框已预先检查。

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

telephone_line = forms.BooleanField(initial=True, help_text="Local telephone line included.")
voice_mail = forms.BooleanField(label="", help_text="Voicemail – included in this bundle.", initial=True)

问题是,当我提交此表单时,即使预先检查了该表单,表单也会给出错误,指出该字段是必需的,然后复选框变为未选中状态。你能不能给我一些帮助,为什么以及如何解决这个问题?

由于

-J

3 个答案:

答案 0 :(得分:2)

这是另一个适用于单个表单和Formsets的选项。 @sandinymyjoints链接到一个好的帖子和接受的答案肯定经过深思熟虑。但是,作为一般规则,黑客请求参数可能会导致很多麻烦。作为一个特定的案例,黑客攻击formset提交的POST涉及正则表达式,这真的很难看。在Formset中(请记住它们是表单的集合),您的表单将以form-0-telephone_lineform-0-voice_mail等方式发布。试试这个。

在Form类中定义两个字段 - 一个看起来不错的可见字段和一个用于携带数据的隐藏字段。可见的复选框将被禁用,因此永远不会POST(如您所知),但它将为用户提供清晰的视觉指示。隐藏的复选框将保持您的初始True检查状态。

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

    telephone_line = forms.BooleanField(initial=True,
                                        widget=forms.HiddenInput)
    telephone_line_visible = forms.BooleanField(initial=True,
                                                required=False,
                                                label="Telephone line",
                                                help_text="Local telephone line included.")

或者,如果您想将“黑客”代码完全保留在一个位置:

def __init__(self, *args, **kwargs):
        super(HomePhoneBundleOrderForm, self).__init__(*args, **kwargs)

        # Hack
        self.fields['telephone_line'].widget=forms.HiddenInput()
        self.fields['telephone_line_visible'] = forms.BooleanField(initial=True,
                                                                   required=False,
                                                                   label="Telephone line",
                                                                   help_text="Local telephone line included.")
        self.fields['telephone_line_visible'].widget.attrs['disabled'] = 'disabled'

答案 1 :(得分:0)

我认为您遇到的问题与此相同:disabled field is not passed through - workaround needed

  

“由于您正在禁用小部件而不是字段,因此就表单而言,它始终不会为fieldA接收任何内容,并且始终无法通过验证。”

有关可能的解决方案,请参阅该问题的已接受答案。看起来最好的方法是修改POST以将所需的值放入字段中。

答案 2 :(得分:0)

在使用javascript / jQuery提交之前,您可以尝试在客户端启用它们,类似于:

//enable disabled fields so they would get submitted with the request
$('#form').submit(function() {
    $('input,select', this).prop('disabled', '');
    return true;
});