【问题标题】:Change a Django form field to a hidden field将 Django 表单字段更改为隐藏字段
【发布时间】:2011-10-15 06:58:03
【问题描述】:

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

在我看来,在某些情况下,我想对用户隐藏它,并尽量保持表单尽可能相似。将此字段转换为 HiddenInput 字段的最佳方法是什么?

我知道我可以在字段上设置属性:

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

我可以设置所需的初始值:

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

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

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

【问题讨论】:

    标签: python html django django-forms


    【解决方案1】:

    如果您有自定义模板和视图,您可以排除该字段并使用{{ modelform.instance.field }} 获取值。

    您也可能更喜欢在视图中使用:

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

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

    希望对你有帮助。

    【讨论】:

    • 使用此解决方案后,我在 is_valid 方法中最终得到"" is not a valid value for a primary key.
    • 听起来很奇怪。我认为它与其他东西有关,您是否将您正在创建的对象的主键显示为 HiddenInput?如果是,您不应该这样做。
    • 也许这是不言而喻的,但您需要先导入表单才能使用。 from django import forms
    • 在 1.7 上使用此语法:hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput()) 其中关键是最后更新的小部件语法。根据您的需要进行调整。
    【解决方案2】:

    首先,如果您不希望用户修改数据,那么简单地排除该字段似乎更简洁。将其包含为隐藏字段只会添加更多数据以通过网络发送,并在您不希望恶意用户修改时邀请他们进行修改。如果您确实有充分的理由包含该字段但将其隐藏,则可以将关键字 arg 传递给模型窗体的构造函数。可能是这样的:

    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)
    

    我更喜欢这种在视图中修改模型窗体的内部结构的方法,但这只是个人喜好问题。

    【讨论】:

    • 只是简单的提示,kwargs.pop('hide_condition', False) 而不是 kwargs['hide_condition']。您将处理 no arg 情况,同时拥有 default 和 del。
    • 感谢 christophe31 的提示。我已根据您的建议进行了更新,因为它使代码更加清晰。
    • 这种方法可以完全隐藏字段吗?就像你设置class Meta: exclude = ["fieldname"]一样。这里的问题是,元方法是“静态的”,但我需要一些动态的东西。见stackoverflow.com/questions/20243735/…
    • You cab di def __init__(self, hide_condition=True, *args, **kwargs) 这是最干净的方式...
    【解决方案3】:

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

    【讨论】:

    • 这是最好的答案恕我直言。我一直讨厌使用我的“控制器”Python 代码来确定表单域的显示。
    • 我经常用crispyforms 制作通用表单模板。如果您使用crispyforms 或在简单的forloop 中显示字段,因为您希望在表单类中使用表单结构,则在表单中覆盖小部件是一种好方法。但是,如果您将表单渲染管理到模板中,确实,这个解决方案更加清晰/干净。
    • 值得注意的是,这似乎会删除您事先应用于该领域的所有类...
    【解决方案4】:

    一个对我有用的选项,将原始表单中的字段定义为:

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

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

    【讨论】:

      【解决方案5】:

      对于普通形式,你可以这样做

      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()
      

      【讨论】:

        【解决方案6】:

        您可以只使用 css :

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

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

        【讨论】:

          【解决方案7】:

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

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

          如果您希望有条件地隐藏该字段,您可以执行以下操作:

          form = MyForm()
          if condition:
              form.fields["field_name"].widget = forms.HiddenInput()
              form.fields["field_name"].initial = "value"
          

          【讨论】:

          • @Ashley 这在关键方面有所不同。 ShayRybak 的答案不包括如何向隐藏的输入添加值,我的答案就是这样做
          • @Ashley 是的。该问题询问“制作隐藏字段的最简单的方法是什么”。如果字段总是隐藏(如我的回答中规定),最好在字段定义中设置值
          【解决方案8】:

          模型示例:

          models.py

          from django.db import models
          
          
          class YourModel(models.Model):
              fieldname = models.CharField(max_length=255, default="default")
          

          在您的表单中,您可以使用 ModelForm 添加小部件。要使其隐藏,请添加'type': 'hidden',如下所示?

          forms.py

          from .models import YourModel
          from django import forms
          
          
          class YourForm(forms.ModelForm):
          
          
              class Meta:
                  model = YourModel
                  fields = ('fieldname',)
          
                  widgets = {
                      'fieldname': forms.TextInput(attrs={'type': 'hidden'}),
                  }
          

          如果你不知道如何将它添加到你的 views.py 文件中,这里有一些关于它的视频。

          如果您使用基于函数的视图

          https://www.youtube.com/watch?v=6oOHlcHkX2U


          如果你使用基于类的视图

          https://www.youtube.com/watch?v=KB_wDXBwhUA

          【讨论】:

            【解决方案9】:
            {{ form.field}}
            {{ form.field.as_hidden }}
            

            使用这种 jinja 格式,我们可以同时拥有可见的表单字段和隐藏的表单字段。

            【讨论】:

            • {{ form.field.as_hidden }} 的使用解决方案已经在this answer 中给出。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-17
            • 2014-11-26
            • 1970-01-01
            • 2017-02-28
            • 1970-01-01
            • 2018-11-29
            相关资源
            最近更新 更多