django为Form生成的label标签添加class
原创
骑士救兵2018-05-25 12:54:41著作权
文章分类
python自动化开发问题集
阅读数
21059
©著作权归作者所有:来自51CTO博客作者骑士救兵的原创作品,如需转载,请注明出处,否则将追究法律责任
https://blog.51cto.com/steed/2120211
使用Form生成html标签的时候,虽然提供了widget的方法可以自定义标签的要是,但是只能给生成的input标签添加样式,对于生成的label标签无法添加样式。而很多场景下需要为label和input都添加class以实现自定义样式。
# 测试环境
创建一个Form,通过Form帮我们生成HTML:
```python
# urls.py 文件,对应关系
path('email/', views.email),
# forms.py 文件
from django.forms import Form
from django.forms import fields
from django.forms import widgets
class UserEmail(Form):
username = fields.CharField()
password = fields.CharField(
widget=widgets.PasswordInput(attrs={'class': 'c1'})
)
email = fields.EmailField(
widget=widgets.EmailInput(attrs={'class': 'c1'})
)
# views.py 文件
def email(request):
obj = forms.UserEmail()
print(obj['email'].label_tag(attrs={'class': 'c1'})) # 其实生成标签的方法是提供attrs参数的
return render(request, 'demo/email.html', {'obj': obj})
```
在html中,直接使用Form帮我生成的表单:
```html
{{ obj.as_p }}
{{ obj.email.label_tag }}
{{ obj.email }}
```
这里可以看到,input标签里都是有class属性的,但是lable标签里没有,并且Form组件里貌似也没有提供为label标签增加自定义属性的方式。
# 通过模板语言的自定义函数实现
上面的views里的 `print(obj['email'].label_tag(attrs={'class': 'c1'}))` ,从输出看,django提供的生成label标签的方法是支持attrs参数实现自定义属性的,问题是在前端使用模板语言的时候只能这样 `{{ obj.email.label_tag }}` 无法传入参数。这里就自定义个模板语言的函数来解决这个问题。
## 自定义函数
要自定义函数,按照下面的步骤操作:
1. 在APP下,创建templatetags目录,目录名字很重要不能错。
2. 创建任意 .py 文件,这里文件名随意,比如:myfun.py。
3. 文件里创建一个template.Library()对象,名字是register。这里的对象名字必须是register。
4. 然后写自己的函数,但是都用@register.simple_tag这个装饰器装饰好:
自定义的函数如下:
```python
# app名/templatetags/myfun.py 文件
from django import template
register = template.Library()
@register.filter(is_safe=True)
def label_with_classes(value, arg):
return value.label_tag(attrs={'class': arg})
```
然后在页面中使用自定义的函数:
```html
{{ obj.as_p }}
{{ obj.email.label_tag }}
{{ obj.email }}
{% load myfun %}
{{ obj.email|label_with_classes:'c1 c2' }}
```
**注意,上面的自定义函数引用的时候参数和参数之间一定不能有空格。**
这里还有一个好处,把添加前端样式的代码放到了前端的html里实现了。
## 为input标签也写一个自定义函数
django默认的方法是在Form里,通过widgets小部件添加attrs参数来实现标签的自定义样式。这是在放在后端实现的。上面已经实现了前端的自定义样式,这里找了到生成input标签的方法,就是as_widget()。照着样子再写一个子定义函数:
```python
# app名/templatetags/myfun.py 文件
from django import template
register = template.Library()
@register.filter()
def label_with_classes(value, arg):
return value.label_tag(attrs={'class': arg})
@register.filter()
def widget_with_classes(value, arg):
return value.as_widget(attrs={'class': arg})
```
最后,上面搞得难么麻烦,主要是为了可以前端一个for循环,就能把表单按自定义的样式显示出来:
```html
{% load myfun %}
{% for item in obj %}
{{ item|label_with_classes:'col-sm-2 control-label' }}
{{ item|widget_with_classes:'form-control' }}
{% endfor %}
```
1赞
1收藏
评论