java中的接口是类吗
331
2022-08-29
django学习第十四天--Forms和ModelForm(django formset)
Forms和ModelForm
进行数据校验,先看数据校验的过程
注册页面图解: 前端为了用户体验会做一些校验,不满足校验要求会报错 服务端也会对数据进行一些校验,不满足校验要求会报错 数据库也会对数据进行一些校验,不满足校验要求会报错 form组件和modleform组件就是让我们的数据校验过程更加简单一些,功能非常强大
Forms组件
提供了三个功能
1.能够帮我们生成HTML标签 2.标签中保留之前用户输入的数据 3.数据校验
forms组件的使用流程
1.在views.py文件中创建一个自定义的form类
from django import forms #需要先导入这个forms class RegisterForm(forms.Form): phone = forms.CharField() username = forms.CharField() password = forms.CharFied() #用label参数可以将HTML中的label标签中内容显示为中文 phone = forms.CharField(label='手机号') username = forms.CharField(label='用户名') password = forms.CharField(label='密码')
2.在views.py文件中写上视图函数
def register(request): if request.method == 'GET': form = RegisterForm() #将上面的form类进行实例化 return render(request,'register.html',{'form':form})#将实例化后的对象返回到html中生成对应的属性的标签
3.创建一个html文件,比如叫作register.html,内容如下
保留原数据和校验功能
forms组件代码
class RegisterForm(forms.Form): #每个字段,默认都有一个required=True的参数,表示该字段数据不能为空 #phone = form.CharField(label='手机号',required=True) phone = forms.CharField( label='手机号', required=True, #错误提示信息的自定制 error_messages={ 'required':'小敏敏提示您,不能为空!', } ) username = forms.CharField(label='用户名') password = forms.CharField(label='密码')
views.py内容如下
def register(request): if request.method == 'GET': form = RegisterForm() return render(request,'register.html',{'form':form}) else: print(request.POST) form = RegisterForm(data=request.POST) #把数据交给了RegisterForm,那么在通过form来渲染标签时,就将原来的的数据以默认值的形式(value='值')生成在了对应标签上 if form.is_valid(): #执行校验,如果所有数据都校验通过了,返回True,但凡有一个数据没有通过校验,返回False print('通过校验的数据',form.cleaned_data) return HttpResponse('ok') print('错误信息>>>',form.errors) return render(request,'register.html',{'form':form})
register.html内容
RegexValidator验证器
示例代码
from django.core.validators import RegexValidator class DataForm(forms.Form): #不能为空,长度不能超过10位,不能短于4位 username = forms.CharField( ... #RegexValidator('正则','不符合正则时的错误信息') validators=[RegexValidator(r'^a','用户名必须以a开头'),RegexValidator(r'b$','用户名必须以b结尾')] )
校验函数
示例
import re from django.core.validators import RegexValidator from django.core.exceptions import ValidationError #ValidationError是django提供的一个数据校验失败的一个错误类型 #先定义一个函数,函数中我们可以做数据的校验,如果数据校验失败,我们可以raise ValidationError('错误信息') def mobile_match(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手机号格式有误') 使用 phone =forms.CharField( label='手机号', validators=[mobile_match,], #列表里面写我们自己定义的函数名 )
局部钩子
代码示例
class DataForm(forms.Form): #不能为空,长度不能超过10位,不能短于4位 username = forms.CharField( label='用户名', max_length=10, min_length=4, ) #可以为空 phone = forms.CharField( required=False, validators=[mobile_match,], ) 。。。 #局部钩子,能够对username这个字段的数据进行一个更高级的校验 #语法 clean_字段名称 def clean_username(self): uname = self.cleaned_data.get('username') #cleaned_data.get 获取数据 if '666' in uname: raise ValidationError('不能光喊6,没有用') #如果校验通过,需要return这个值 return uname def clean_phone(self): pass
全局钩子
示例代码
class DataForm(forms.Form): #密码 password = forms.CharField() #再次确认密码 confirm_password=forms.CharField() #多个字段进行比较时,一般都是用全局钩子固定函数名clean def clean(self): p1 = self.cleaned_data.get('password') p2 = self.cleaned_data.get('confirm_password') if p1 != p2: #直接raise错误,这个错误信息保存到了全局错误信息里面 #也就是self.errors里面 #所以要用add_error('属性名','错误提示信息') self.add_error('confirm_password','抱歉,两次密码不一致') self.add_error('password','抱歉,两次密码不一致') #如果校验通过,必须return self.cleaned_data return self.cleaned_data
源码部分,主要看cleaned_data,为什么会在没有走视图函数的时候,就能获取数据
def _clean_fields(self): for name, field in self.fields.items(): # print(name, field) # name属性名称,field是CharField()类的实例化对象 # value_from_datadict() gets the data from the data dictionaries. # Each widget type knows how to retrieve its own data, because some # widgets split data over several HTML fields. if field.disabled: value = self.get_initial_for_field(field, name) else: value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) try: if isinstance(field, FileField): initial = self.get_initial_for_field(field, name) value = field.clean(value, initial) else: # 将CharField中的max_length,required.. value = field.clean(value) # 将属性对应的CharField里面的简单校验规则进行了校验 self.cleaned_data[name] = value #self.cleaned_data['username'] = 'abc' if hasattr(self, 'clean_%s' % name): #clean_username value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value except ValidationError as e: self.add_error(name, e)
简单总结
首先对所有的我们自己定义的类中的属性进行循环,self.fields能够获取到所有的属性,循环过程中先对属性,比如username=form.CharField(max_length=12),里面的参数校验规则进行了校验,这个校验完成之后,给self.clean_data这个字典进行了赋值 self.clead_data['username'] ='sad'然后对该字段的局部钩子进行了校验,在局部钩子中我们可以拿到self.clean_data['username']这个数据进行处理,别忘了局部钩子校验成功之后,要return这个字段的值,然后才进入下一次循环,处理下一个属性当上面的所有循环执行完之后,才执行我们的全局钩子,全局钩子中校验成功之后别忘了return self.clean_data
静态文件配置和templates模板配置
可以在app01/app02应用文件夹下分别创建一个static名称的文件夹,存放自己应用的静态文件 可以在app01/app02应用文件夹下分别创建一个templates名称的文件夹,存放自己应用的html文件 django寻找html文件静态文件的查找顺序是先找总配置中的templates或者statics文件夹,如果找不到对应文件,就去每个应用下的static或者templates去找对应文件,顺序是按照settings.py配置文件中的INDSTALL_APP中注册app的顺序进行查找,找到就返回,不在继续往下找了,所以要注意,最好在static或者templates下面创建一个以应用名为名称的文件夹,将文件放到这里面,以防文件名冲突导致的问题。
-------------------------------------------
个性签名:代码过万,键盘敲烂!!!
如果觉得这篇文章对你有小小的帮助的话,记得“推荐”哦,博主在此感谢!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~