Django:如何用自定义类全局覆盖textarea



我正在尝试在Django中全局覆盖小部件(如textarea(。

为此,我定义了自己的django/form/widgets/textarea.html文件。

首先,我想修改默认的行数。textarea.html文件将如下所示:

<textarea
rows="3"
name="{{ widget.name }}"
{% include "django/forms/widgets/attrs.html" %}
>{% if widget.value %}{{ widget.value }}{% endif %}</textarea>

上面的这个例子非常有效。

但是如果我现在想添加一个自定义类呢?

<textarea
rows="3"
class="my-custom-class"
name="{{ widget.name }}"
{% include "django/forms/widgets/attrs.html" %}
>{% if widget.value %}{{ widget.value }}{% endif %}</textarea>

这不会像预期的那样工作,因为attrs.html应该处理像class这样的额外属性。因此,直接在文本区域中定义类属性将打破这种行为,并删除现有的类。

什么是";"干净";如何在全局范围内添加额外的类?完全去掉include是可以接受的吗?

我想用HTML来做,而不是用Python。例如,当我定义表单时,我不想定义一个新的Widget,它将继承自基本Widget,因为我认为这是纯粹的标记主题,不应该干扰表单定义本身。

编辑:我怀疑这个软件包可以帮助

谢谢。

在这个问题的帮助下,我找到了一个解决方案。如果你认为你有更好的,可以随意改进。

TL/DR:我们正在构建一个自定义过滤器来检测小部件的类型,将类映射到它,然后使用django小部件调整将类注入字段,而不更改现有的类。

现在,我可以从一个地方自定义所有的小部件类,而无需Python继承,也无需重写Django小部件html文件。

模板标签

from django import template
register = template.Library()
BASIC_INPUT = "border border-indigo-300 px-2.5 py-1.5 rounded-md focus:outline-none"
mapping = {
"Select": BASIC_INPUT,
"TextInput": BASIC_INPUT,
"EmailInput": BASIC_INPUT,
"RegionalPhoneNumberWidget": BASIC_INPUT,
"ModelSelect2": "",  # let the default markup
# add all widgets you could use, or use a default one and override the others.
}

@register.filter("get_field_classes")
def get_field_classes(field):
widget_class_name = field.field.widget.__class__.__name__
try:
return mapping[widget_class_name]
except KeyError:
# you could use default classes rather than raising an error if you prefer
raise ValueError(f"Classes related to {widget_class_name} are not defined yet")

然后在您的默认表单模板(例如:django/forms/default.html(中,在浏览字段时,借助django小部件调整包:

{% load widget_tweaks %}
{% load get_field_classes %}
{% for field in form.visible_fields %}
{# .... #}
<div>
{% with field_classes=field|get_field_classes %}
{{ field|add_class:field_classes }}
{% endwith %}
</div>
{% endfor %}

最新更新