欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

markdownpad2 html渲染组件出错_Day68 Django forms组件

发布时间:2025/4/16 编程问答 57 豆豆
生活随笔 收集整理的这篇文章主要介绍了 markdownpad2 html渲染组件出错_Day68 Django forms组件 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

目录

  • forms组件
  • forms组件类书写
  • forms组件如何校验数据
  • forms组件如何渲染标签
  • forms组件展示错误信息
  • forms组件钩子函数(HOOK)
  • forms组件常见参数
  • forms组件源码

1、forms组件

小示例:
写一个注册功能:
利用form表单提交数据,获取用户名密码,在后端判断用户名密码是否符合条件:用户名不能包含abc字符串,密码不能少于6位数。

views.py文件:

from django.shortcuts import render# Create your views here. def ab_form(request):back_dic = {'username':'','password':''}if request.method == 'POST':username = request.POST.get('username')password = request.POST.get('password')if 'abc' in username:back_dic['username'] = '用户名不能包含字符串abc'if len(password)<6:back_dic['password'] = '密码必须为6位数'# back_dic字典值默认是空,当用户输入用户名密码并提交时,就发起了post请求,back_dic通过校验如果不符合要求就会传值return render(request,'ab_form.html',locals())

html页面:

<body> <form action="" method="post"><p>username:<input type="text" name="username"><span style="color: red">{{ back_dic.username }}</span></p><p>password:<input type="password" name="password"><span style="color: red">{{ back_dic.password }}</span></p><input type="submit" class="btn btn-info" value="submit"> </form> </body>

以上我们就手动完成了需求:
1、书写前端获取用户数据的HTML代码
2、后端对用户数据进行校验
3、对不符合要求的数据进行前端提示

实际上以上功能form组件都能完成(渲染代码、校验数据、前端展示提示)。

应用场景:例如博客园的注册页面

数据校验前端可有可无,但是后端必须要有!因为前端的校验你可以直接修改,或者利用爬虫程序绕过前端页面直接朝后端提交数据。

2、forms组件类书写

views.py文件中:

from django import forms class MyForm(forms.Form):# username,password这两个字段最少3位数,最大8位数username = forms.CharField(min_length=3,max_length=8)password = forms.CharField(min_length=3,max_length=8)# email字段必须符合邮箱格式,xx@xx.comemail = forms.EmailField()

3、forms组件如何校验数据

测试环境的准备除了我们之前用的tests.py,在pycharm里面已经给我们提供了一个Django的测试环境:点击Python Console:

校验步骤:
1、将要校验的数据组织成形式传入
2、判断数据是否合法,is_valid()方法用来校验我们传入的字典数据是否合法,该方法只有在所有的数据全部合法的情况下才会返回True
3、cleaned_data拿到所有符合条件的数据;
4、errors拿到所有不符合校验规则的数据以及不符合规则的原因,以键值对的形式展现,并且值是以列表的形式,因为一个字段有可能会不符合多个规则。


如果我再多传入一个hobby键:
form_obj = views.MyForm({'username':'jack','password':'12','email':'123','hobby':'study'})那么hobby是不会被校验的,只会找MyForm类里面书写的字段去做校验,而hobby不会被放到cleaned_data也不会被放到errors中。
默认情况下,类里面的所有字段都必须传值。如果少传了一个键,少传的那个字段会被放到errors中:
form_obj = views.MyForm({'username':'jack','password':'123'})
form_obj.errors
{'email': ['This field is required.']}
form_obj.cleaned_data
{'username': 'jack', 'password': '123'}

4、forms组件如何渲染标签

结合form组件获取用户注册的用户名密码邮箱,有了form组件之后所有获取用户输入的标签都不需要自己写了。form组件不会帮你渲染提交按钮,要自己添加。

views.py文件:

from django import forms class MyForm(forms.Form):# username,password这两个字段最少3位数,最大8位数username = forms.CharField(min_length=3,max_length=8,label='用户名')password = forms.CharField(min_length=3,max_length=8,label='密码')# email字段必须符合邮箱格式,xx@xx.comemail = forms.EmailField(label='邮箱')def index(request):# 1、先产生一个空对象form_obj = MyForm()# 2、直接将该空对象传递给HTML页面return render(request,'index.html',locals())

前端index.html页面(前端对生成的空对象做操作):
label属性默认展示的是类中字段首字母大写的形式,也可以修改:通过给字段加label属性。

<body> <form action="" method="post"><p>第一种form表单渲染方式:</p><p>代码书写极少,封装程度太高,不利于后续的扩展,一般只在本地测试使用</p><p>as_p</p>{{ form_obj.as_p }}<p>as_ul</p>{{ form_obj.as_ul }}<p>as_table</p>{{ form_obj.as_table }}<p>第二种form表单渲染方式:</p><p>可扩展性强,但是需要书写的代码太多,一般不用</p><p>{{ form_obj.username.label }} :{{ form_obj.username }}</p><p>{{ form_obj.password.label }} :{{ form_obj.password }}</p><p>{{ form_obj.email.label }} :{{ form_obj.email }}</p><p>第三种form表单渲染方式:</p><p>代码书写简单,扩展性高,推荐使用</p>{% for form in form_obj %}<p> {{ form.label }} :{{ form }} </p>{% endfor %}</form> </body>

5、forms组件展示错误信息

浏览器会自动帮你做校验(如下图的提示信息),但是前端的校验还是不安全,我们可以给form表单加个参数取消前端浏览器自动校验功能:<form action="" method="post" novalidate>

form表单展示错误信息需要注意:
1、get请求和post请求传给页面的对象变量名必须一致form_obj
2、当你的数据不合法时,form组件会保存你输入的数据,让你基于上次的输入数据进行修改,更加人性化

views.py文件

from django import forms class MyForm(forms.Form):# username,password这两个字段最少3位数,最大8位数username = forms.CharField(min_length=3,max_length=8,label='用户名',error_messages={'min_length':'用户名最少3位','max_length':'用户名最多8位','required':'用户名不能为空'})password = forms.CharField(min_length=3,max_length=8,label='密码',error_messages={'min_length': '密码最少3位','max_length': '密码最多8位','required': '密码不能为空'})# email字段必须符合邮箱格式,xx@xx.comemail = forms.EmailField(label='邮箱',error_messages={'invalid':'邮箱格式不正确','required': '邮箱不能为空'})def index(request):# 1、先产生一个空对象form_obj = MyForm()if request.method == 'POST':# 3、校验数据form_obj = MyForm(request.POST)# 4、判断数据是否合法if form_obj.is_valid():# 5、如果合法,操作数据库存储数据return HttpResponse('OK')# 5、如果不合法,将错误信息展示到前端# 2、直接将该空对象传递给HTML页面return render(request,'index.html',locals())

index.html页面:

<body> <form action="" method="post" novalidate>{% for form in form_obj %}<p> {{ form.label }} :{{ form }} {# form.errors.0这后面加了一个.0表示只拿列表第一个错误信息,就不会自动帮你生成ul标签 #}<span style="color:red">{{ form.errors.0 }}</span></p>{% endfor %}<button>提交</button> </form> </body>

在给字段添加了error_messages参数之后,错误提示就变成自己输入的了(自定义)。

6、forms组件钩子函数

钩子函数:在特定的节点自动触发完成响应操作
在form组件中有两类钩子
1、局部钩子
当你需要给某个字段增加校验规则的时候可以使用,在后端校验的基础上进行二次校验。
2、全局钩子
当你需要给多个字段增加校验规则的时候可以使用。

实际案例:
1、校验用户名中不能包含666(只需要校验用户名,可以用局部钩子)
2、校验密码和确认密码是否一致(校验密码字段和确认密码字段,需要用全部钩子)

views.py文件做如下修改:

from django import forms class MyForm(forms.Form):# username,password这两个字段最少3位数,最大8位数username = forms.CharField(min_length=3,max_length=8,label='用户名',error_messages={'min_length':'用户名最少3位','max_length':'用户名最多8位','required':'用户名不能为空'})password = forms.CharField(min_length=3,max_length=8,label='密码',error_messages={'min_length': '密码最少3位','max_length': '密码最多8位','required': '密码不能为空'})confirm_password = forms.CharField(min_length=3,max_length=8,label='确认密码',error_messages={'min_length': '密码最少3位','max_length': '密码最多8位','required': '密码不能为空'})# email字段必须符合邮箱格式,xx@xx.comemail = forms.EmailField(label='邮箱',error_messages={'invalid':'邮箱格式不正确','required': '邮箱不能为空'})# 局部钩子def clean_username(self):# 获取用户名username = self.cleaned_data.get('username')if '666' in username:# 提示前端展示错误信息# 提示方式1:self.add_error('username','用户名不能包含666')# 提示方式2(繁琐,一般不用):# raise ValidationError('用户名不能包含666.')# 将钩子函数钩取出来的数据再放回去return username# 全局钩子def clean(self):# 获取两个密码字段password = self.cleaned_data.get('password')confirm_password = self.cleaned_data.get('confirm_password')if not confirm_password == password:self.add_error('confirm_password','两次密码不一致')# 校验后将全局钩子钩出来的数据再放回去return self.cleaned_data

7、forms组件常见参数

label='用户名',设置字段名
error_messages={'min_length': '密码最少3位',},自定义报错信息
initial='jack',默认值
required=False,设置成必填字段
widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2'}),调整样式(多个属性值用空格隔开即可)
from django.core.validators import RegexValidator
class MyForm(Form):
user = fields.CharField(validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
),支持字段写正则表达式,可以写多个正则一一匹配

其他类型渲染:
radiocheckboxselectDjango Form表单组件 - JasonJi - 博客园​www.cnblogs.comclass LoginForm(forms.Form):...hobby = forms.MultipleChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),label="爱好",initial=[1, 3],widget=forms.widgets.CheckboxSelectMultiple()) keep = forms.ChoiceField(label="是否记住密码",initial="checked",widget=forms.widgets.CheckboxInput()) hobby = forms.MultipleChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),label="爱好",initial=[1, 3],widget=forms.widgets.SelectMultiple())

针对字段的校验方式:
1、最简单的max_length,min_length
2、正则validator
3、钩子函数

8、forms组件源码

切入点:form_obj.is_valid()

def is_valid(self):"""Returns True if the form has no errors. Otherwise, False. If errors arebeing ignored, returns False."""return self.is_bound and not self.errors # 如果is_valid要返回true的话,那么self.is_bound要为true,self.errors要为false # self.is_bound = data is not None or files is not None # 所以只要你传数据了,那么self.is_bound就是true@propertydef errors(self):"Returns an ErrorDict for the data provided for the form"if self._errors is None:self.full_clean()return self._errors# forms组件所有功能基本都出自于该方法:def full_clean(self):self._clean_fields() # 校验字段+局部钩子self._clean_form() # 全局钩子self._post_clean()forms组件源码​www.bilibili.com

总结

以上是生活随笔为你收集整理的markdownpad2 html渲染组件出错_Day68 Django forms组件的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。