Django框架进阶7 forms组件(pycharm内置测试环境Python Console), cookie与session操作
Posted 战斗小人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django框架进阶7 forms组件(pycharm内置测试环境Python Console), cookie与session操作相关的知识,希望对你有一定的参考价值。
forms组件
写一个注册页面 获取用户输入的用户名和密码
用户点击注册发送到后端做用户名密码的校验
用户名中不能包含金瓶mei 不符合社会主义核心价值观
密码不能为空 你个DSB,密码怎么能为空
1.手写获取用户输入的前端页面代码 渲染页面 2.后端获取用户数据并做合法性校验 校验数据 3.将校验之后的结果渲染到前端页面 展示信息
不用forms组件代码:
app01/views.py
from django.shortcuts import render,HttpResponse # Create your views here. def register(request): error_dic = {\'username\':\'\',\'password\':\'\'} if request.method == \'POST\': username = request.POST.get(\'username\') password = request.POST.get(\'password\') if \'金瓶mei\' in username: error_dic[\'username\'] = \'不符合社会主义核心价值观\' if not password: error_dic[\'password\'] = \'密码不能为空\' return render(request,\'register.html\',locals())
templates/register.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <form action="" method="post"> <p>username: <input type="text" name="username"> <span style="color: red">{{ error_dic.username }}</span> </p> <p>password: <input type="text" name="password"> <span style="color: red">{{ error_dic.password }}</span> </p> <input type="submit"> </form> </body> </html>
pycharm内置测试环境:Python Console
forms组件
1.渲染页面
2.校验数据
3.展示信息
需要先写一个类
from django import forms class MyRegForm(forms.Form): # 用户名最少3位 最多8位 username = forms.CharField(max_length=8,min_length=3) password = forms.CharField(max_length=8,min_length=3) # email字段必须填写符合邮箱格式的数据 email = forms.EmailField()
如何校验数据
# 1.传入待校验的数据 用自己写的类 传入字典格式的待校验的数据 form_obj = views.MyRegForm({\'username\':\'jason\',\'password\':\'12\',\'email\':\'123456\'}) # 2.判断数据是否符合校验规则 form_obj.is_valid() # 该方法只有在所有的数据全部符合校验规则才会返回True False # 3.如何获取校验之后通过的数据 form_obj.cleaned_data {\'username\': \'jason\'} # 4.如何获取校验失败及失败的原因 form_obj.errors { \'password\': [\'Ensure this value has at least 3 characters (it has 2).\'], \'email\': [\'Enter a valid email address.\'] } # 5.注意 forms组件默认所有的字段都必须传值 也就意味着传少了是肯定不行的 而传多了则没有任何关系 只校验类里面写的字段 多传的直接忽略了 form_obj = views.MyRegForm({\'username\':\'jason\',\'password\':\'123456\'}) form_obj.is_valid() Out[12]: False form_obj.errors Out[18]: {\'email\': [\'This field is required.\']} form_obj = views.MyRegForm({\'username\':\'jason\',\'password\':\'123456\',"email":\'123@qq.com\',"hobby":\'hahahaha\'}) form_obj.is_valid() Out[14]: True form_obj.cleaned_data Out[15]: {\'username\': \'jason\', \'password\': \'123456\', \'email\': \'123@qq.com\'} form_obj.errors Out[16]: {}
如何渲染页面
先写一个继承forms的类
forms组件只帮你渲染获取用户输入(输入 选择 下拉 文件)的标签 不渲染按钮和form表单标签
渲染出来的每一个input提示信息都是类中字段首字母大写
{#<p>第一种渲染方式:多个p标签 本地测试方便 封装程度太高了 不便于扩展</p>#} {#{{ form_obj.as_p }}#} {#{{ form_obj.as_ul }}#} {#{{ form_obj.as_table }}#} {#<p>第二种渲染方式:扩展性较高 书写较为繁琐</p>#} {#<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label> {# 给label赋id值 #} {#{{ form_obj.username }}#} {#{{ form_obj.password.label }}{{ form_obj.password }}#} {#{{ form_obj.email.label }}{{ form_obj.email }}#} <p>第三种渲染方式 推荐使用</p> {% for form in form_obj %} <p>{{ form.label }}{{ form }}</p> {% endfor %}
如何渲染错误信息
前端
<form action="" method="post" novalidate> {# 取消前端校验,前端校验只能显示第一个错误,而且不安全 #} {% for form in form_obj %} <p> {{ form.label }}{{ form }} {# 另外注意这个是模板语法 .0索引不会因为对象为空出现超出报错#} <span>{{ form.errors.0 }}</span> {# 容器类型(此处为列表)会自动被渲染成ul套li形式,加.0固定写法,拿到内部信息 #} </p> {% endfor %} <input type="submit"> </form>
后端
def reg(request): # 1.先生成一个空的类对象 form_obj = MyRegForm() if request.method == \'POST\': # 3 获取用户数据并交给forms组件校验 request.POST 字典类型 form_obj = MyRegForm(request.POST) # 4 获取校验结果 if form_obj.is_valid(): return HttpResponse(\'数据没问题\') else: # 5 获取校验失败的字段和提示信息 print(form_obj.errors) # 2直接将该对象传给前端页面 return render(request,\'reg.html\',locals())
数据校验一个前后端都得有 但是前端的校验弱不禁风 可有可无
而后端的校验则必须非常全面
如何取消浏览器自动帮我们校验的功能
form表单取消前端浏览器自动校验功能
<form action="" method="post" novalidate>
常用参数
label input的提示信息
error_messages 自定义报错的提示信息
required 设置字段是否允许为空
initial 设置默认值
widget 控制type类型及属性
widget=forms.widgets.TextInput(attrs={\'class\':\'form-control c1 c2\'}) # form-control占满一行 widget=forms.widgets.PasswordInput(attrs={\'class\':\'form-control\'})
例:
class MyRegForm(forms.Form): # 用户名最少3位 最多8位 username = forms.CharField(max_length=8,min_length=3,label=\'用户名\', #label不写,默认为字段名首字母大写 error_messages={ \'max_length\':\'用户名最长8位\', \'min_length\':\'用户名最短3位\', \'required\':\'用户名不能为空\' },required=False, # 可以不填,为空 initial=\'jason\', # 默认值 widget=forms.widgets.TextInput(attrs={\'class\':\'form-control c1 c2\'}) ) password = forms.CharField(max_length=8,min_length=3,label=\'密码\', widget=forms.widgets.PasswordInput(attrs={\'class\':\'form-control\'})) # email字段必须填写符合邮箱格式的数据 email = forms.EmailField(label=\'邮箱\',error_messages={ \'required\':\'邮箱必填\', \'invalid\':\'邮箱格式不正确\' })
钩子函数
全局钩子(针对多个字段)
校验密码与确认面是否一致
局部钩子(针对单个字段)
校验用户名不能包含666
# 全局钩子 注意如果有错误,页面并不会刷新,输入的数据还在,因为下方reg函数 def clean(self): # 钩子函数已被封装,固定名。会在上面MyRegForm输入参数第一层校验通过后,进行第二层校验 # 校验密码和确认密码是否一致 password = self.cleaned_data.get(\'password\') confirm_password = self.cleaned_data.get(\'confirm_password\') if not password == confirm_password: # 展示提示信息 self.add_error(\'confirm_password\',\'两次密码不一致\') return self.cleaned_data # 拿全局数据,要返回全局数据
# 局部钩子 def clean_username(self): username = self.cleaned_data.get(\'username\') if \'666\' in username: self.add_error(\'username\',\'光喊666是不行的\') return username # 拿了局部数据,要返回局部数据
app01/views.py
from django.shortcuts import render,HttpResponse # Create your views here. def register(request): error_dic = {\'username\':\'\',\'password\':\'\'} if request.method == \'POST\': username = request.POST.get(\'username\') password = request.POST.get(\'password\') if \'金瓶mei\' in username: error_dic[\'username\'] = \'不符合社会主义核心价值观\' if not password: error_dic[\'password\'] = \'密码不能为空\' return render(request,\'register.html\',locals()) from django import forms from django.forms import widgets from django.core.validators import RegexValidator # 导入正则表达式 class MyRegForm(forms.Form): # 用户名最少3位 最多8位 username = forms.CharField(max_length=8,min_length=3,label=\'用户名\', #label不写,默认为字段名首字母大写 error_messages={ \'max_length\':\'用户名最长8位\', \'min_length\':\'用户名最短3位\', \'required\':\'用户名不能为空\' },required=False, # 可以不填,为空 initial=\'jason\', # 默认值 # widget=forms.widgets.TextInput(attrs={\'class\':\'form-control c1 c2\'}) ) password = forms.CharField(max_length=8,min_length=3,label=\'密码\', # widget=forms.widgets.PasswordInput(attrs={\'class\':\'form-control\'}) ) confirm_password = forms.CharField(max_length=8,min_length=3,label=\'密码\', # widget=forms.widgets.PasswordInput(attrs={\'class\':\'form-control\'}) ) # email字段必须填写符合邮箱格式的数据 email = forms.EmailField(label=\'邮箱\',error_messages={ \'required\':\'邮箱必填\', \'invalid\':\'邮箱格式不正确\' }) phone = forms.CharField( validators=[ RegexValidator(r\'^[0-9]+$\',\'请输入数字\'), RegexValidator(r\'^159[0-9]+$\',\'数字必须以159开头\') ] ) # 全局钩子 注意如果有错误,页面并不会刷新,输入的数据还在,因为reg函数 def clean(self): # 钩子函数已被封装,固定名。会在上面MyRegForm输入参数第一层校验通过后,进行第二层校验 # 校验密码和确认密码是否一致 password = self.cleaned_data.get(\'password\') confirm_password = self.cleaned_data.get(\'confirm_password\') if not password == confirm_password: # 展示提示信息 self.add_error(\'confirm_password\',\'两次密码不一致\') return self.cleaned_data # 拿全局数据,要返回全局数据 # 局部钩子 def clean_username(self): username = self.cleaned_data.get(\'username\') if \'666\' in username: self.add_error(\'username\',\'光喊666是不行的\') return username # 拿了局部数据,要返回局部数据 def reg(request): # 1.先生成一个空的类对象 form_obj = MyRegForm() if request.method == \'POST\': # 3 获取用户数据并交给forms组件校验 request.POST form_obj = MyRegForm(request.POST) # 4 获取校验结果 if form_obj.is_valid(): return HttpResponse(\'数据没问题\') # return render(request, \'reg.html\', locals()) else: # 5 获取校验失败的字段和提示信息 print(form_obj.errors) # 2直接将该对象传给前端页面 return render(request,\'reg.html\',locals())
templates/reg.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> {#<p>第一种渲染方式:多个p标签 本地测试方便 封装程度太高了 不便于扩展</p>#} {#{{ form_obj.as_p }}#} {#{{ form_obj.as_ul }}#} {#{{ form_obj.as_table }}#} {#<p>第二种渲染方式:扩展性较高 书写较为繁琐</p>#} {#<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label> {# 给label赋id值 #} {#{{ form_obj.username }}#} {#{{ form_obj.password.label }}{{ form_obj.password }}#} {#{{ form_obj.email.label }}{{ form_obj.email }}#} <p>第三种渲染方式 推荐使用</p> <form action="" method="post" novalidate> {# 取消前端校验,前端校验只能显示第一个错误,而且不安全 #} {% for form in form_obj %} <p> {{ form.label }}{{ form }} <span>{{ form.errors.0 }}</span> {# 容器类型(此处为列表)会自动被渲染成ul套li形式,加.0固定写法,拿到内部信息 #} </p> {% endfor %} <input type="submit"> </form> </body> </html>
forms补充知识点
正则校验
from django import forms from django.core.validators import RegexValidator # 导入正则表达式 class MyRegForm(forms.Form): phone = forms.CharField( validators=[ RegexValidator(r\'^[0-9]+$\',\'请输入数字\'), RegexValidator(r\'^159[0-9]+$\',\'数字必须以159开头\') ] )
渲染选择框,下拉框
from django import forms from django.forms import widgets from django.core.validators import RegexValidator ################了解知识点(指定去哪里拷贝即可)################ gender = forms.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性别", initial=3, widget=forms.widgets.RadioSelect() ) hobby = forms.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=3, widget=forms.widgets.Select() ) hobby1 = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple() ) keep = forms.ChoiceField( label="是否记住密码", initial="checked", widget=forms.widgets.CheckboxInput() ) hobby2 = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget以上是关于Django框架进阶7 forms组件(pycharm内置测试环境Python Console), cookie与session操作的主要内容,如果未能解决你的问题,请参考以下文章