Django形式:在验证之间保持禁用字段

shy*_*ent 7 python django django-forms

在某些时候,我需要显示类型的"disabled"(灰色disabled="disabled"属性)输入"select".如标准(xhtml和html4)中所指定的,类型的输入"select"不能具有该"readonly"属性.请注意,这仅用于演示目的,实际值必须以POST结尾.所以这就是我所做的(引用django中表单声明的一部分):

from django import forms

_choices = ['to be', 'not to be']
class SomeForm(forms.Form):
    field = forms.ChoiceField(choices=[(item, item) for item in _choices],
                   widget=forms.HiddenInput()) # the real field

    mock_field = forms.ChoiceField(required=False, # doesn't get submitted
                        choices=[(item, item) for item in _choices],
                        label="The question",
                        widget=forms.Select(attrs={'disabled':'disabled'}))
Run Code Online (Sandbox Code Playgroud)

然后它被初始化为:

initial_val = 'to be'
form = SomeForm(ititial={'field':initial_val,
                         'mock_field':initial_val})
Run Code Online (Sandbox Code Playgroud)

一切都很好.好吧,直到表单得到验证并且其中一个字段未通过验证.发生这种情况时,重新加载表单并保留值,但不保留"mock_field"之一 - 它永远不会被提交(它被禁用).所以它没有保留.虽然这不会影响数据完整性,但它仍然不是很好的表示方式.

有没有办法保留这个领域,尽可能少的hackery?表单是a的一部分,django.contrib.formtools.FormWizard初始值(和某些字段)是动态生成的.基本上,已经有很多东西在进行,如果有可能不会使事情过于复杂,那就太棒了.

shy*_*ent 1

好吧,这将是我第一次回答我的问题,但我已经找到了一个解决方案并且(虽然它确实是一个黑客)它有效。

我不是从表单实例获取初始值, -self.fields['whatever'].initial似乎在None构造函数内部,而是从关键字参数“initial”获取值。然后我将其设置为“模拟”字段的唯一选择。像这样:

from django import forms

_choices = ['to be', 'not to be']
class SomeForm(forms.Form):
    field = forms.ChoiceField(choices=[(item, item) for item in _choices],
                   widget=forms.HiddenInput()) # the real field

    mock_field = forms.ChoiceField(required=False, # doesn't get submitted
                        choices=[(item, item) for item in _choices],
                        label="The question",
                        widget=forms.Select(attrs={'disabled':'disabled'}))

    def __init__(self, *args, **kwargs):
        super(SomeForm, self).__init__(*args, **kwargs)
        mock_initial = kwargs['initial']['field']
        self.fields['mock_field'].choices = [(mock_initial, mock_initial),]
Run Code Online (Sandbox Code Playgroud)

这可能需要一些错误处理。显然,如果没有为实际的 提供初始值,这将不起作用field