将Django表单字段更改为隐藏字段


128

我有一个带的Django表单,与RegexField正常的文本输入字段非常相似。

我认为,在某些情况下,我想对用户隐藏它,并尝试使表单尽可能相似。将这个领域变成一个HiddenInput领域的最好方法是什么?

我知道我可以使用以下方法在字段上设置属性:

form['fieldname'].field.widget.attr['readonly'] = 'readonly'

我可以通过以下方式设置所需的初始值:

form.initial['fieldname'] = 'mydesiredvalue'

但是,这不会更改小部件的形式。

什么是使此字段成为<input type="hidden">字段的最佳/最“ django-y” /最不“ hacky”的方法?

Answers:


169

如果您具有自定义模板并查看,则可以排除该字段并用于{{ modelform.instance.field }}获取值。

您也可以在视图中使用:

form.fields['field_name'].widget = forms.HiddenInput()

但我不确定它是否会保护发布后的保存方法。

希望能帮助到你。


1
&quot;&quot; is not a valid value for a primary key.使用此解决方案后,我在is_valid方法中最终得到一个。
Jens Timmerman 2014年

听起来很奇怪 我认为这与其他内容有关,您是否将HiddenInput显示为正在创建的对象的主键?如果是,则不应该。
christophe31,2014年

也许这不用说,但是您需要先导入表单,然后才能起作用。from django import forms
teewuane 2014年

2
在1.7上,使用以下语法:hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())其中的键是最后的新小部件语法。根据您的需要进行调整。
2014年

195

这也可能有用: {{ form.field.as_hidden }}


3
这是恕我直言的最佳答案。我一直讨厌使用我的“控制器” Python代码来确定表单字段的显示。
trpt4him

我经常用crispyforms制作通用表单模板。如果您使用crisplyforms或在简单的forloop中显示字段,因为您想在表单类中使用表单结构,则在表单中覆盖小部件是一种很好的方法。但是,如果您将表单呈现管理到模板中,那么实际上,此解决方案更加清晰/干净。
christophe31

值得注意的是,这似乎抹去了您之前应用于该领域的所有课程……
John Aaron

59

一个对我有用的选项,将字段的原始形式定义为:

forms.CharField(widget = forms.HiddenInput(), required = False)

那么当您在新的类中覆盖它时,它将保留它的位置。


45

首先,如果您不希望用户修改数据,则仅排除该字段似乎更干净。将其包含为隐藏字段只会增加更多数据以通过有线方式发送,并在您不希望恶意用户修改时邀请它们进行修改。如果确实有理由包括该字段但将其隐藏,则可以将关键字arg传递给modelform的构造函数。可能是这样的:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        hide_condition = kwargs.pop('hide_condition',None)
        super(MyModelForm, self).__init__(*args, **kwargs)
        if hide_condition:
            self.fields['fieldname'].widget = HiddenInput()
            # or alternately:  del self.fields['fieldname']  to remove it from the form altogether.

然后在您看来:

form = MyModelForm(hide_condition=True)

在视图中,我更喜欢这种方法来修改模型形式的内部,但这只是一个问题。


11
只是一个简单的技巧,kwargs.pop('hide_condition',False)而不是kwargs ['hide_condition']。您将处理no arg情况,同时使用默认值和del。
christophe31,

2
谢谢提示,christophe31。我已经根据您的建议进行了更新,因为它使代码更加清晰。
rych 2011年

1
是否可以用这种方法完全隐藏领域?就像您开启一样class Meta: exclude = ["fieldname"]。这里的问题是,元方法是“静态的”,但是我需要动态的东西。见stackoverflow.com/questions/20243735/...
Themerius

你叫def __init __(self,hide_condition = True,* args,** kwargs),这是最干净的方法……
Visgean Skeloru

22

对于正常形式,您可以

class MyModelForm(forms.ModelForm):
    slug = forms.CharField(widget=forms.HiddenInput())

如果您有模型表格,则可以执行以下操作

class MyModelForm(forms.ModelForm):
    class Meta:
        model = TagStatus
        fields = ('slug', 'ext')
        widgets = {'slug': forms.HiddenInput()}

您也可以覆盖__init__方法

class Myform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(Myform, self).__init__(*args, **kwargs)
        self.fields['slug'].widget = forms.HiddenInput()

1

如果要始终隐藏该字段,请使用以下命令:

class MyForm(forms.Form):
    hidden_input = forms.CharField(widget=forms.HiddenInput(), initial="value")

0

您可以只使用css:

#id_fieldname, label[for="id_fieldname"] {
  position: absolute;
  display: none
}

这将使该字段及其标签不可见。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.