Django:<ul>在字段的help_text中

Posted

技术标签:

【中文标题】Django:<ul>在字段的help_text中【英文标题】:Django: <ul> inside help_text of field 【发布时间】:2018-08-20 13:29:01 【问题描述】:

我想在 django 表单字段的 help_text 中有一个 &lt;ul&gt;

不幸的是,django 将 help_text 呈现在 &lt;span&gt; 中。

根据 html 规范,&lt;span&gt; 不得包含 &lt;ul&gt;。至少我的验证工具是这么说的。

这里是django的源码:https://github.com/django/django/blob/master/django/forms/forms.py#L283

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

我该怎么做才能在help_text 有效的html中获得&lt;ul&gt;

覆盖as_table() 不起作用,因为表单来自“core_app”而字段来自插件。两者都是两个不同的 git repos,我不想仅仅因为这个而修改核心。

【问题讨论】:

我认为覆盖 as_table 会有所帮助(对于您想要的特定形式)。 或者,根本不要使用as_table,并以您想要的格式单独输出您的字段。 @itzMEonTV 覆盖 as_table() 不起作用。我更新了问题。感谢您的反馈。 @DanielRoseman 我更新了问题。表单来自核心,help_text 来自插件...... 我不知道这对我的评论有何影响。如文档中所述,as_table 纯粹是一种方便的方法;如果输出格式不适合您的需要,请不要使用。 【参考方案1】:

正如您已经提到的,在 HTML 中有 blockinline 元素的概念。 简而言之,块元素生成一个新行,并且可能包含其他块元素和内联元素。内联元素不生成新行,可能包含其他内联元素,但不包含块元素。

MDN 网络文档提供了有关 block 和 inline 元素的更多信息。

由于span 是一个内联元素,所以你不能将ul 这个块级元素放在里面。或者,你可以,但它不是一个有效的 HTML,这不是你想要的。

由于您使用的是第三方代码,修改它可能会带来其他问题。 你可以分叉,修改你需要的部分,然后使用你的分叉。但是当第三方代码更新时,你必须重复整个过程。

在这种情况下,您可以这样做monkey patching。 因此,对于您的特定问题,我们可以这样做:

from django import forms

class MyBaseForm(forms.BaseForm):
    def as_table(self):
        "Return this form rendered as HTML s -- excluding the ."
        return self._html_output(
            normal_row='%(label)s%(errors)s%(field)s%(help_text)s',
            error_row='%s',
            row_ender='',
            help_text_html='<div class="helptext">%s</div>',
            errors_on_separate_row=False)

BaseForm.as_table = MyBaseForm.as_table

您可以将此代码放在您的forms.py 或任何其他适合您的文件中。

现在help_text 将呈现为div 元素,这是一个块级元素。你可以在里面放一个无序列表ul,并且有一个有效的HTML。

猴子补丁并不是解决问题的最佳方式,但在我看来,它是克服一些棘手问题的务实方式。

【讨论】:

在我的情况下,该字段是在插件中创建的,并且表单来自核心(两个不同的 git repos)。我可以从插件中修补核心,但这可能会产生不必要的副作用。我想在这种情况下我会忽略 html-validation。到目前为止,我没有看到更好的解决方案。 @guettli 我不了解核心应用程序和插件。因此,我可以根据问题中提供的信息写一个答案。你试过我的建议了吗?我假设猴子修补BaseForm 应该会影响第三方插件的行为。【参考方案2】:

我认为您想要的并不是“在您的 help_text 中包含一个 &lt;ul&gt;”,而是“在您的帮助文本中显示一个项目符号列表”。

因此,如果您无法覆盖as_table() 或使用as_table() 以外的其他内容,我希望您仍然能够更改样式表。在这种情况下,您可以使用span 伪造您的ul

from django.utils.safestring import mark_safe

help_text=mark_safe(
    '<span class="fake-ul">'
    '<span class="fake-li">foo</span>'
    '<span class="fake-li">bar</span>'
    '</span>'
)

这是你的 CSS:

.fake-ul 
  display: block;
  padding-left: 40px;
  list-style-type: disc;

.fake-li 
  display: list-item;

【讨论】:

我也喜欢这个主意。它将所有内容外包给 CSS,并且不会与 Python 代码混淆。我想补充一点,为了正确解析,help_text 的值应该作为参数传递给django.utils.safestring.mark_safe。否则 HTML 标签将分别转换为&amp;lt;&amp;gt;【参考方案3】:

所以可能为时已晚,但我认为您可能会发现 Django widget tweaks 有用。

【讨论】:

我会赞成这个答案,但它至少应该包括一个最小的例子。在目前的形式中,它是一个仅限链接的答案。 这很公平,我明天可以添加示例

以上是关于Django:<ul>在字段的help_text中的主要内容,如果未能解决你的问题,请参考以下文章

Django框架模版渲染与过滤器使用

Django学习手册 - 自定义分页工具

Django模板语言-Tags

在 Django 模板中使用 form.as_ul 时控制表单错误显示。

如何将标签添加到Django管理员字段

如何更改 django 日期时间格式输出?