【问题标题】:How do I hide the field label for a HiddenInput widget in Django Admin?如何在 Django Admin 中隐藏 HiddenInput 小部件的字段标签?
【发布时间】:2010-11-27 09:26:42
【问题描述】:

我有一些看起来像这样的 Django 表单代码:

class GalleryAdminForm(forms.ModelForm):
    auto_id=False
    order = forms.CharField(widget=forms.HiddenInput())

这使得表单字段消失了,但它在 Django 管理页面中留下了“订单”标签。如果我使用:

order = forms.CharField(widget=forms.HiddenInput(), label='')

我仍然在字段和标签原来的位置之间留下“:”。

我如何隐藏整个事情?!

【问题讨论】:

标签: python django django-admin


【解决方案1】:

如果您使用的是 JQuery,这应该可以解决问题:

您的表单

TO_HIDE_ATTRS = {'class': 'hidden'}
class GalleryAdminForm(forms.ModelForm):
    auto_id=False
    order = forms.CharField(widget=forms.TextInput(attrs=TO_HIDE_ATTRS))

要添加到模板的 JavaScript 代码

$(document).ready(function(){
    $('tr:has(.hidden)').hide();
});

如果您将表单呈现为表格,这将有效。如果你想让它与任何类型的表单渲染一起工作,你可以这样做:

$(document).ready(function(){
    $('{{ form_field_container }}:has(.hidden)').hide();
});

并将form_field_container 添加到您的模板上下文中。一个例子:

如果你这样渲染你的表单:

    <form>
        <span>{{ field.label_tag }} {{ field }}</span>
    </form>

您的上下文必须包括:

'form_field_container': 'span'

你懂的……

【讨论】:

  • 一个更通用的 jQuery 解决方案是使用$('.hidden').parent().hide(),因为这将隐藏包含小部件、标签和任何帮助文本的整个 div。这肯定是一个可行的解决方案。我知道将自定义属性添加到小部件,但试图在不求助于 JS 的情况下完成整个事情。我很惊讶 Django 没有内置的方法来做到这一点。
  • 是的,$('.hidden').parent().hide() also works, but relies in the fact that the parent of your field also contains the label. If you had something like LABEL FIELD ` 它不起作用,因为父级是 TD 标签而不是 TR一。我也很惊讶没有“django 方式”来做到这一点。
  • Insane.. 解决方案 - 就像向苍蝇开火!
  • 同意@YugalJindle。如果可以使用 {% if not field.is_hidden %}{{ field.label }}:{{ field }}{% else %}{{ field }}{% endif %}
  • 很抱歉投了反对票,但我同意,这是在错误的地方解决了这个问题。
【解决方案2】:

我认为通过修改contrib/admin/helpers.py 中的class AdminField(object) 来实现隐藏输入小部件的“:”标签省略更简单:

    if self.is_checkbox:
        classes.append(u'vCheckboxLabel')
        contents = force_unicode(escape(self.field.label))
    else:
        contents = force_unicode(escape(self.field.label)) + u':'

到:

    if self.is_checkbox:
        classes.append(u'vCheckboxLabel')
        contents = force_unicode(escape(self.field.label))
    else:            
        contents = force_unicode(escape(self.field.label))
        #MODIFIED 26/10/2009
        if self.field.label <> '':
           contents += u':'
        # END MODIFY

【讨论】:

  • 这是一个很好的方法,虽然我不喜欢修改 django 核心中的任何内容。可能可以子类化对象并以这种方式实现相同的效果。
【解决方案3】:

我不敢相信有几个人建议为此使用 jQuery...

是否有这样的情况:当你知道的唯一工具是锤子时,所有东西看起来都像钉子?

来吧,如果您要从客户端执行此操作(而不是在后端代码中修复问题的根源),那么正确的执行位置肯定是在 CSS 中吗?

如果您在管理站点中,则有点困难,但如果是常规页面,则很容易从表单模板中省略整个标签,for example

如果您在管理站点中,那么您仍然可以在 GalleryAdminForm 类中覆盖 BaseForm 的 as_table、a​​s_ul、as_p 方法(参见 django/forms/forms.py),以省略标签所在的任何字段的标签空白(或 == ':',因为值可能在这个渲染阶段)

(...查看forms.py 的第 160-170 行,如果标签为空白,Django 1.2 似乎应该正确省略“:”,所以我猜你使用的是旧版本?)

【讨论】:

  • 我猜你一定是管理员,上面@Tonino 指出的代码在管理员表单时将冒号硬编码到标签中,并绕过常规表单机制。我想我会在这种情况下使用 CSS。
  • 查看 Django 1.4.5,这个错误仍然出现在管理表单中。 The template calls .label_tag 其中adds a colon unconditionally。我认为正确的服务器端解决方案是更改管理模板。
  • hi @WilfredHughes :) 看起来这是在 Django 主干中修复的(你可以给表单构造函数一个label_suffix!)...问题仍然存在于 1.5.1 并更改管理模板以省略 {{ field.label_tag }} 在需要的地方似乎是最好的方法
  • 啊,原来如此。这是一个很好的解决方法,但有一个 open ticket 听起来像是“正确”的解决方案。
  • 我添加了一个答案,说明如何解决这个问题。哎呀,这不是一件容易解决的事情。
【解决方案4】:

Create a hidden field in the admin site 上查看答案,通过覆盖admin/includes/fieldset.html 可以在不使用JavaScript 的情况下完成。从那里,您可以注入一个CSS 类,然后完成剩下的工作。

【讨论】:

    【解决方案5】:

    试试

    {% for field in form.visible_fields %}

    【讨论】:

    • 点个赞。我不敢相信 JQuery kludges 和 CSS hacks 越来越受欢迎。这是一个更好的解决方案。
    • 我会投票,但它会留下隐藏的字段。来自@emispowder 的更完整的解决方案。
    【解决方案6】:

    Oraculum 做对了。你不应该在客户端清理这个。如果它很混乱,那么你根本不应该将它发送给客户。基于 Oraculum 的回答,您应该使用自定义表单模板,因为您可能仍需要表单中的隐藏值。

    {% for field in form.visible_fields %}
        <div>
            {{ field.errors }}
            <span class="filter-label">{{ field.label_tag }}</span><br>
            {{ field }}
        </div>
     {% endfor %}
    
     {% for field in form.hidden_fields %}
         <div style="display:none;">{{ field }}</div>
     {% endfor %}
    

    使用自定义表单模板来控制隐藏字段更简洁,因为它不会向客户端发送无关信息。

    【讨论】:

      【解决方案7】:

      理论上,您应该可以将label_suffix 传递给表单构造函数。但是,Django 管理员忽略了这一点。

      您已经被 Django 中的两个错误所困扰:#18134 'BoundField.label_tag should include form.label_suffix'(固定在主干中,应该在 1.6 中)和较小程度的#11277 Hidden fields in Inlines are displayed as empty rows

      目前,最好的解决方案是覆盖管理字段集模板。为您的小部件使用 HiddenInput,然后覆盖管理字段集模板 (documented here)。只需使用以下内容创建一个templates/admin/includes/fieldset.html

      <fieldset class="module aligned {{ fieldset.classes }}">
          {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
          {% if fieldset.description %}
              <div class="description">{{ fieldset.description|safe }}</div>
          {% endif %}
          {% for line in fieldset %}
              <div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}">
                  {% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}
                  {% for field in line %}
                      <div{% if not line.fields|length_is:'1' %} class="field-box{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}"{% endif %}>
                          {% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %}
                          {% if field.is_checkbox %}
                              {{ field.field }}{{ field.label_tag }}
                          {% else %}
                              {# only show the label for visible fields #}
                              {% if not field.field.is_hidden %}
                              {{ field.label_tag }}
                              {% endif %}
      
                              {% if field.is_readonly %}
                                  <p>{{ field.contents }}</p>
                              {% else %}
                                  {{ field.field }}
                              {% endif %}
                          {% endif %}
                          {% if field.field.help_text %}
                              <p class="help">{{ field.field.help_text|safe }}</p>
                          {% endif %}
                      </div>
                  {% endfor %}
              </div>
          {% endfor %}
      </fieldset>
      

      【讨论】:

        【解决方案8】:

        根据 Wilfried Hughes 的解决方案,我更改了 fieldset.html,几乎没有改进。

        下面的代码 sn-p 不仅隐藏了输入元素,如果字段集只包含一个输入类型设置为隐藏的元素,它还隐藏了周围的 div 元素,不浪费表单中的空间。

        <fieldset class="module aligned {{ fieldset.classes }}">
        {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
        {% if fieldset.description %}
            <div class="description">{{ fieldset.description|safe }}</div>
        {% endif %}
        {% for line in fieldset %}
            <div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}"{% if line.fields|length_is:'1' %}{% for field in line %}{% if field.field.is_hidden %} style="display: none"{% endif %}{% endfor %}{% endif %}>
                {% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}
                {% for field in line %}
                    <div{% if not line.fields|length_is:'1' %} class="field-box{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}"{% endif %}{% if field.field.is_hidden %} style="display: none"{% endif %}>
                        {% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %}
                        {% if field.is_checkbox %}
                            {{ field.field }}{{ field.label_tag }}
                        {% else %}
                            {# only show the label for visible fields #}
                            {% if not field.field.is_hidden %}
                            {{ field.label_tag }}
                            {% endif %}
        
                            {% if field.is_readonly %}
                                <p>{{ field.contents }}</p>
                            {% else %}
                                {{ field.field }}
                            {% endif %}
                        {% endif %}
                        {% if field.field.help_text %}
                            <p class="help">{{ field.field.help_text|safe }}</p>
                        {% endif %}
                    </div>
                {% endfor %}
            </div>
        {% endfor %}
        

        【讨论】:

        • 只是为了添加到这个有用的帖子中。我相信这个模板适用于 1.6。 @Lacki,你能验证一下吗?
        【解决方案9】:

        以下内容会从您的所有表单字段中删除“:”。我只用forms.Form 类尝试过,但我相信它也应该适用于forms.ModelForm

        在 Django 表单中,标签后的“:”是label_suffix。您可以通过创建ModelForm 的子类(此处称为UnstyledForm)并重新定义初始化函数并将label_suffix 设置为空字符串来更改或删除label_suffix。然后使用新的UnstyledForm 类。

        class UnstyledForm(forms.ModelForm):
            def __init__(self, *args, **kwargs):
                kwargs.setdefault('label_suffix', '')
                super(UnstyledForm, self).__init__(*args, **kwargs)
        
        class GalleryAdminForm(UnstyledForm):
            auto_id=False
            order = forms.CharField(widget=forms.HiddenInput())
        

        希望对你有帮助!

        【讨论】:

          【解决方案10】:

          另一种方法,但我认为迭代 form.visible_fields 和 form.hidden_​​fields 会更好

          <form action="{% url 'some_url' param %}" method="POST">
              {% csrf_token %}
              <div class="row">
                  {% for field in form %}
          
                      {% if not field.is_hidden %}
                          <div class="col-md-6">
                              {{ field.label_tag }}
                              {{ field.error }}
                              {{ field }}
                          </div>
                      {% else %}
                          {{ field }}
                      {% endif %}
                  {% endfor %}
               </div>
          </form>
          

          【讨论】:

            猜你喜欢
            • 2011-02-10
            • 2011-10-08
            • 2012-05-07
            • 2011-07-25
            • 1970-01-01
            • 2014-05-03
            • 2016-05-31
            • 1970-01-01
            • 2011-09-28
            相关资源
            最近更新 更多