使用Form生成html标签的时候,虽然提供了widget的方法可以自定义标签的要是,但是只能给生成的input标签添加样式,对于生成的label标签无法添加样式。
而很多场景下需要为label和input都添加class以实现自定义样式。
测试环境
创建一个Form,通过Form帮我们生成HTML:
# 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帮我生成的表单:
<body> {{ obj.as_p }} {{ obj.email.label_tag }} {{ obj.email }} </body>
这里可以看到,input标签里都是有class属性的,但是lable标签里没有,并且Form组件里貌似也没有提供为label标签增加自定义属性的方式。
通过模板语言的自定义函数实现
上面的views里的 print(obj['email'].label_tag(attrs={'class': 'c1'})) ,从输出看,django提供的生成label标签的方法是支持attrs参数实现自定义属性的,问题是在前端使用模板语言的时候只能这样 {{ obj.email.label_tag }} 无法传入参数。这里就自定义个模板语言的函数来解决这个问题。
自定义函数
要自定义函数,按照下面的步骤操作:
在APP下,创建templatetags目录,目录名字很重要不能错。
创建任意 .py 文件,这里文件名随意,比如:myfun.py。
文件里创建一个template.Library()对象,名字是register。这里的对象名字必须是register。
然后写自己的函数,但是都用@register.simple_tag这个装饰器装饰好:
自定义的函数如下:
# 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})
然后在页面中使用自定义的函数:
<body> {{ obj.as_p }} {{ obj.email.label_tag }} {{ obj.email }} {% load myfun %} {{ obj.email|label_with_classes:'c1 c2' }} </body>
注意,上面的自定义函数引用的时候参数和参数之间一定不能有空格。
这里还有一个好处,把添加前端样式的代码放到了前端的html里实现了。
为input标签也写一个自定义函数
django默认的方法是在Form里,通过widgets小部件添加attrs参数来实现标签的自定义样式。这是在放在后端实现的。上面已经实现了前端的自定义样式,这里找了到生成input标签的方法,就是as_widget()。
照着样子再写一个子定义函数:
# 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循环,就能把表单按自定义的样式显示出来:
<body> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> {% load myfun %} <form class="form-horizontal"> {% for item in obj %} <div class="form-group"> {{ item|label_with_classes:'col-sm-2 control-label' }} <div class="col-sm-10"> {{ item|widget_with_classes:'form-control' }} </div> </div> {% endfor %} </form> </body>
补充知识:Django Forms组件 的参数配置案例 input样式, 渲染的标签加class 错误信息提示
Forms渲染出标签类型
密码型、文本型、邮箱型框
from django.forms import widgets # 自定义格式方法 class UserForm(forms.Form): '''最小4位 且 模式:普通文本''' name = forms.CharField(min_length=4, label='姓名:',widget=widgets.TextInput()) '''最小4位 且 模式:密码模式''' pwd = forms.CharField(min_length=4, label='密码:', widget=widgets.PasswordInput())
渲染时添加属性 class=''(便于bootstrap)
from django.forms import widgets '''在widgets.类型(加入字典形式的标签信息)''' class UserForm(forms.Form): # 模式:普通文本 标签加上:class="form-control" name = forms.CharField(widget=widgets.TextInput(attrs={'class': 'form-control'})) # 模式:密码模式 标签加上:class="form-control" pwd = forms.CharField(widget=widgets.PasswordInput( attrs={'class': 'form-control'} ))
渲染自定义错误提示
视图
from django.forms import widgets '''追加error_messages参数 dict型式''' class UserForm(forms.Form): # 模式:required=不能为空的提示 name = forms.CharField(min_length=4, label='姓名:', error_messages={ 'title': {'required': '不能为空哦亲亲'}, 'price': {'invalid': '格式错误(提示方法)'}, # '字段': {'错误类型': '提示信息'} }) # 模式:invalid=格式错误 pwd = forms.CharField(min_length=4, label='密码:', error_messages={ 'title': {'required': '不能为空哦亲亲'}, 'price': {'invalid': '格式错误(提示方法)'}, # '字段': {'错误类型': '提示信息'} })
HTML展示错误信息
<form action="" method="post" novalidate="novalidate"> <!--要自定义提示必须 novalidate="novalidate"--> {% csrf_token %} {% for field in form %} <p> {{ field.label }}{{ field }} <span>{{ field.errors.0 }}</span> <!--错误信息固定:field.errors.0 --> </p> {% endfor %} <p><input type="submit" value="提交"></p> </form>
以上这篇django为Form生成的label标签添加class方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持自学编程网。
- 本文固定链接: https://www.zxbcw.cn/post/186974/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)