编辑 Django _form.as_p

问题描述 投票:0回答:6

默认情况下 _form.as._p 吐出:

<p><label for="id_subject">Subject:</label>
    <input id="id_subject" type="text" name="subject" maxlength="100" /></p>

而我需要

 <p><label for="id_subject">Subject:</label><p>
    <input id="id_subject" type="text" name="subject" maxlength="100" /></p>

标签和输入之间有一个中断。我如何修改我的 Django 代码来做到这一点?

django django-forms
6个回答
49
投票

您根本无法再使用

form.as_p
。如果默认设置不适合您,那么您必须手动渲染字段:

<form action="/contact/" method="post">
    {% for field in form %}
        <div class="fieldWrapper">
            {{ field.errors }}
            {{ field.label_tag }}: {{ field }}
        </div>
    {% endfor %}
    <p><input type="submit" value="Send message" /></p>
</form>

请参阅文档:https://docs.djangoproject.com/en/dev/topics/forms/#looping-over-the-form-s-fields


7
投票

如果您只是需要休息一下,则无需更改 Django 代码。只需使用 CSS 将

label
样式设置为
display: block


7
投票

在表单类上覆盖 as_p。

class MyForm(forms.Form):
    def as_p(self):
        "Returns this form rendered as HTML <p>s."
        return self._html_output(
            normal_row = u'<p%(html_class_attr)s>%(label)s</p> %(field)s%(help_text)s',
            error_row = u'%s',
            row_ender = '</p>',
            help_text_html = u' <span class="helptext">%s</span>',
            errors_on_separate_row = True)

3
投票

与布莱恩上面描述的差不多。我会为您的表单编写一个新方法,例如 as_myp。这是我为自己做的。我采用 as_table 方法并使用 as_plain 来删除 tr/th 标记。例如

class MyForm(forms.Form):
    my_field1 = forms.CharField(...)
    my_field2 = forms.WhateverField(...)

    def as_myp(self):
        "Returns this form rendered as HTML <p>s."
        return self._html_output(
            normal_row = '<p%(html_class_attr)s>%(label)s</p> <p>%(field)s%(help_text)s</p>',
            error_row = '%s',
            row_ender = '</p>',
            help_text_html = ' <span class="helptext">%s</span>',
            errors_on_separate_row = True)

    def as_plain(self):
        "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
        return self._html_output(
            normal_row = '%(label)s%(errors)s%(field)s%(help_text)s',
            error_row = '%s',
            row_ender = ' ',
            help_text_html = '<br /><span class="helptext">%s</span>',
            errors_on_separate_row = False)

这似乎比编写模板文件并处理带有错误、标签、可见/隐藏等的表单字段渲染更容易。


0
投票

您可以通过提供替代的

p.html
模板并在 {{ form.as_p }} 中指向它来更改
Form.template_name_p
渲染 html 的方式。

这可能是表单定义:

class SomeForm(forms.Form):
    template_name_p = 'some_app/p.html'  # The new template for as_p() 

这是默认的p.html(位于django/forms/templates/django/forms/p.html):

{{ errors }}
{% if errors and not fields %}
  <p> {% for field in hidden_fields %}{{ field }}{% endfor %}</p>
{% endif %}
{% for field, errors in fields %}
  {{ errors }}
  <p {% with classes=field.css_classes %}{% if classes %} class="{{ classes }}"{% endif %}{% endwith %}>
    {% if field.label %}{{ field.label_tag }}{% endif %}
    {{ field }}
    {% if field.help_text %}
      <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
    {% endif %}
    {% if forloop.last %}
      {% for field in hidden_fields %}{{ field }}{% endfor %}
    {% endif %}
  </p>
{% endfor %}
{% if not fields and not errors %}
  {% for field in hidden_fields %}{{ field }}{% endfor %}
{% endif %}

它创建了OP想要避免的html,即:

<p>
    <label for="id_email">Email:</label>
    <input type="email" ... [attributes removed for brevity] >
</p>

这是修改后的 p.html,其中对

{{ field }}
的调用包装在其自己的
p
元素中。 (我还将父级
p
更改为
div
,因为 Chrome 不喜欢嵌套
p
标签)。

{{ errors }}
{% if errors and not fields %}
  <p>{% for field in hidden_fields %}{{ field }}{% endfor %}</p>
{% endif %}
{% for field, errors in fields %}
  {{ errors }}
  <div {% with classes=field.css_classes %}{% if classes %} class="{{ classes }}"{% endif %}{% endwith %}>
    {% if field.label %}{{ field.label_tag }}{% endif %}
    <p>
      {{ field }}
    </p>  <!-- New: p tag wraps field -->
    {% if field.help_text %}
      <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
    {% endif %}
    {% if forloop.last %}
      {% for field in hidden_fields %}{{ field }}{% endfor %}
    {% endif %}
  </div>
{% endfor %}
{% if not fields and not errors %}
  {% for field in hidden_fields %}{{ field }}{% endfor %}
{% endif %}

这个替代方案 p.html 可以放置在相关的应用程序模板目录中,如 some_app/templates/some_app/p.html。它生成了我认为OP想要的html。

<div>
    <label for="id_email">Email:</label>
    <p>
      <input type="email" ... [attributes removed for brevity] >
    </p>
</div>

文档参考:https://docs.djangoproject.com/en/5.0/ref/forms/api/#as-p


-6
投票

模板:

<div id="my_form">
    {{ form.as_p }}
</div>

CSS:

#my_form p label,
#my_form p input{
    float: left;
    clear: left;
}

因此,如果您添加字段,您仍然可以使用 form.as_p

© www.soinside.com 2019 - 2024. All rights reserved.