将类添加到 Django label_tag() 输出
我需要某种方法将类属性添加到表单字段的 label_tag()
方法的输出中。
我看到可以传入 attrs
字典,并且我已经在 shell 中测试了它,我可以执行以下操作:
for field in form:
print field.label_tag(attrs{'class':'Foo'})
我将看到 class='Foo'
在我的输出中,但我没有看到从模板添加 attrs
参数的方法 - 事实上,模板是专门针对此而设计的,不是吗?
我的表单定义中有没有办法定义要在标签中显示的类?
在表单中,我可以执行以下操作来为输入提供一个类,
self.fields['some_field'].widget.attrs['class'] = 'Foo'
我只需要让它输出 的类。
I need some way to add a class attribute to the output of the label_tag()
method for a forms field.
I see that there is the ability to pass in an attrs
dictionary and I have tested it in the shell and I can do something like:
for field in form:
print field.label_tag(attrs{'class':'Foo'})
I will see the class='Foo'
in my output, but I don't see a way to add an attrs
argument from the template - in fact, templates are designed specifically against that, no?
Is there a way in my form definition to define the class to be displayed in the label?
In the form, I can do the following to give the inputs a class
self.fields['some_field'].widget.attrs['class'] = 'Foo'
I just need to have it output the class for the <label />
as well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
技术 1
我对另一个答案的断言提出异议,即过滤器将“不太优雅”。 正如您所看到的,它确实非常优雅。
在模板中使用它同样优雅:
技术 2
或者,我发现的更有趣的技术之一是:将 * 添加到必填字段。
您为 BoundField.label_tag 创建一个装饰器,它将通过适当设置的 attrs 来调用它。 然后你猴子修补 BoundField 以便调用 BoundField.label_tag 调用装饰函数。
Technique 1
I take issue with another answer's assertion that a filter would be "less elegant." As you can see, it's very elegant indeed.
Using this in a template is just as elegant:
Technique 2
Alternatively, one of the more interesting technique I've found is: Adding * to required fields.
You create a decorator for BoundField.label_tag that will call it with attrs set appropriately. Then you monkey patch BoundField so that calling BoundField.label_tag calls the decorated function.
如何将 CSS 类添加到 forms.py 中的表单字段,例如:
然后我只需在模板中执行以下操作:
当然,这可以轻松修改为在模板中的 for 循环标记中工作。
How about adding the CSS class to the form field in the forms.py, like:
then I just do the following in the template:
Of course this can easily be modified to work within a for loop tag in the template.
自定义模板标签 似乎是解决方案。 自定义过滤器也可以,尽管它可能不太优雅。 但在这两种情况下,您都需要回退到自定义表单呈现。
如果这是一项非常重要的任务; 我将创建一个 Mixin,它允许我使用标签类注释表单字段,并使用这些类提供表单渲染方法。 这样下面的代码就可以工作:
但我想问; 你真的需要标签标签上的类吗? 我的意思是 HTML 设计方面。 是否绝对有必要在其中添加一个类? 难道不能用像这样的CSS来解决吗:
我有时使用 jQuery 对于这种情况; 如果它有效,它会改进页面,但如果它不起作用,也不会是一场灾难。 并保持 HTML 源代码尽可能精简。
A custom template tag seems to be the solution. A custom filter would also do, although it can be less elegant. But you would need to fall back to custom form rendering in both cases.
If this is a task of high importance; I'd create a Mixin that allows me to annotate the form fields with label classes and supplies form rendering methods using those classes. So that the following code works:
But I'd like to ask; Do you really need a class on the label tag? I mean HTML design-wise. Is it absolutely necessary to add a class in there? Couldn't it be solved with some CSS like:
I sometimes use jQuery for such cases where; it will improve the page if it works, but it won't be a disaster if it doesn't. And keep the HTML source as lean as possible.
我同意第一个答案,使用 css 可以做到这一点,但是。
这是 django 源代码中的原因是什么?
在 django.forms.forms.py 中,有一个定义显示有在标签中显示
attrs
的代码:但是
_html_output
调用这个函数时没有 attrs:所以看来 django 是部分的准备这样做但实际上并没有使用它。
I am agree with answer number one, with css this could be done, but.
What is the reason for this to be in django source?
In django.forms.forms.py there's this definition that shows there's code to display
attrs
in labels:but
_html_output
calls this function without attrs:So it seems that django is partially prepared to do this but actually it does not use it.
有点晚了,但遇到了类似的问题。 希望这对您有帮助。
A bit too late but came across a similar problem. Hope this helps you.
您需要更改 BoundField 类中的方法 label_tag ,并在表单中使用它
You need change method label_tag in BoundField class, and use it in form
我们还可以使用 {{field.label}} 和 {{field.id_for_label}}
在 HTML 中呈现为-
we can also use {{field.label}} and {{field.id_for_label}}
<label class="your_class_name" id="{{form.link.id_for_label}}">{{form.link.label}}</label>
Render in HTML as-
注意:希望即将推出的 Django 4.0 将使这变得更加容易,因为它提供了 基于模板的表单渲染。
在那之前:
OP要求一种使用
user240515 和 user2732686 的回答确实提供了一些实施建议,但没有提供任何理由。
大多数基于自定义模板标签的其他解决方案都需要我们手动渲染表单字段,因此如果我们只想使用
{{ form }}
,它们就不起作用。因此,除了所有这些答案之外,这里还尝试提供更多背景信息。
关于 label_tag
表单标签由
BaseForm.as_table()
、as_ul()
或as_p()
呈现 快捷方式,通过“私有”BaseForm._html_output( )
方法,如 来源。这是通过调用
BoundField.label_tag()
来完成的,可以看出 此处。label_tag() 方法采用
attrs
参数以及标记的附加 HTML 属性。
但是,问题是
BaseForm._html_output()
调用label_tag()
而没有attrs
,并且没有简单的替代方法来设置>attrs
参数。如何扩展label_tag?
Django 的
contrib.admin
通过扩展其AdminField
中的label_tag()
方法解决了这个问题,从 来源。要扩展
BoundField.label_tag()
,我们可以 创建自定义BoundField:现在我们可以创建一个具有特定标签属性的绑定字段,但是我们用它做什么呢?
如何使用自定义绑定字段?
绑定字段使用 forms.Field 实例化。 get_bound_field(),因此,我们可以重写该方法以返回自定义绑定字段:
然后我们可以在
Form
上使用自定义字段:但是如果我们想对所有对象执行此操作该怎么办我们的表单字段?
如何为所有表单字段使用自定义绑定字段?
最后,在
BaseForm.__getitem__()
中调用了Field.get_bound_field()
(参见来源)。 这意味着我们可以通过调用例如my_form['some_field']
来获取绑定字段。为了将我们的自定义绑定字段用于所有表单字段,我们可以 monkey patch
field.get_bound_field
对于表单中的所有字段,或者我们可以覆盖表单的__getitem__()
以忽略get_bound_field()
并直接使用MyBoundField
。这是一个覆盖的示例,它主要是 原始来源,除了
MyBoundField
行:最后,这一切对于一些样式来说似乎是一个很多麻烦。
NOTE: Hopefully the upcoming Django 4.0 will make this a whole lot easier, as it offers template based form rendering.
Until then:
The OP asks for a way to use BoundField.label_tag() in a form definition.
The answers by user240515 and user2732686 do provide some suggestions for implementation, but they do not provide any rationale.
Most other solutions based on custom template tags require us to render the form fields manually, so they do not work if we simply want to use
{{ form }}
.Thus, in addition to all those answers, here's an attempt to provide some more background.
About label_tag
Form labels are rendered by the
BaseForm.as_table()
,as_ul()
, oras_p()
shortcuts, via the "private"BaseForm._html_output()
method, as can be seen in the source.This is done by calling
BoundField.label_tag()
, as can be seen here.The label_tag() method takes an
attrs
argument with additional HTML attributes for the<label>
tag.However, the problem is that
BaseForm._html_output()
callslabel_tag()
withoutattrs
, and there is no easy alternative for setting theattrs
argument.How to extend label_tag?
Django's
contrib.admin
solves this problem by extending thelabel_tag()
method in itsAdminField
, as becomes clear from the source.To extend
BoundField.label_tag()
, we can create a customized BoundField:Now we can create a bound field with specific label attributes, but what do we do with it?
How to use a custom bound field?
Bound fields are instantiated using forms.Field.get_bound_field(), so, we could override that method to return our custom bound field:
Then we can use the custom field on our
Form
:But what if we want to do this for all our form fields?
How to use a custom bound field for all form fields?
In the end,
Field.get_bound_field()
is called inBaseForm.__getitem__()
(see source). This means we can get a bound field by calling e.g.my_form['some_field']
.In order to use our custom bound field for all the form's fields, we could either monkey patch
field.get_bound_field
for all fields in the form, or we could override the form's__getitem__()
to ignoreget_bound_field()
and instead useMyBoundField
directly.Here's an example of an override, which is mostly a copy of the original source, except for the
MyBoundField
line:In the end, this all seems like a lot of trouble for a bit of styling.
尝试 django-widget-tweaks
将其添加到项目 settings.py 文件中的 INSTALLED_APPS :
使用add_label_class过滤器:
阅读文档以获取更多信息和功能。
Try django-widget-tweaks
Add it to INSTALLED_APPS in your projects settings.py file:
Use add_label_class filter:
Read the Document to get more information and functions.