前戏
"""
需求:
写一个注册功能
获取用户名和密码 利用form表单提交数据
在后端判断用户名和密码是否符合一定的条件
用户名中不能包含指定字符
密码不能少于三位
如果符合条件需要你将提示信息展示到前端页面
"""
def index(request):
back_dic = {'username': '', 'password': ''}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if 'qwe' in username:
back_dic['username'] = '不符合'
if len(password) < 3:
back_dic['password'] = '太短了'
return render(request, 'index.html', locals())
<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">
</form>
基本使用,校验规则
class MyForm(forms.Form):
username = forms.CharField(min_length=3, max_length=8)
# username 最小三位 最大八位
password = forms.CharField(min_length=3, max_length=8)
email = forms.EmailField()
# email字段必须符合邮箱格式
校验数据
第二种测试环境
python console
第一种测试环境 -- 自建
test需要拷贝代码
from app01 import views
form_obj = views.MyForm({'username': 'json', 'password': '123', 'email': '123.@qq.com'}) # 实例化对象,将待校验数据组织成字典传入
form_obj.is_valid() # 判断传入的所有数据是否合法
False
form_obj.cleaned_data # 返回所有合法的数据
{'username': 'json', 'password': '123'}
form_obj.errors # 返回不合法的数据, 以及不合法的原因
{'email': ['Enter a valid email address.']}
form_obj = views.MyForm({'username': 'json', 'password': '123', 'email': '123@qq.com', 'hobby': 'study'}) # 校验数据只校验类中出现的字段,多穿的不影响
form_obj.is_valid()
True
form_obj = views.MyForm({'username': 'json'}) # 校验数据默认情况下,类中所有数据都必须被传值
form_obj.is_valid()
False
"""
也就意味着校验数据的时候,可以多传,但是不能少传
"""
渲染html代码
"""
forms组件只会自动帮你渲染获取用户输入的数据(input select radio checkbox)
不会帮你渲染提交按钮
"""
<form action="" method="post">
{# <p>第一种渲染方式 封装程度太高了,不便于后续扩展</p>#}
{# {{ form_obj.as_p }}#}
{# {{ form_obj.as_ul }}#}
{# {{ form_obj.as_table }}#}
{# <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>#}
"""
lable 属性默认展示的是字段首字母大写的形式
也可以自己修改,直接给字段对象加lable属性即可
"""
<p>第三张渲染方式 推荐使用</p>
{% for form in form_obj %}
<p>{{ form.label }}: {{ form }}</p>
{% endfor %}
def home(request):
# 1. 先产生一个空对象
form_obj = MyForm()
# 直接将该空对象传递给html页面
return render(request,'home.html', locals())
配置路由
展示提示信息
"""
浏览器会帮你校验数据,但是前端的校验弱不禁风
如何让浏览器不做校验
"""
def home(request):
# 1. 先产生一个空对象
form_obj = MyForm() # get请求
if request.method=='POST':
"""
1, 数据获取繁琐
2. 校验数据需要构造成字典的格式传入
"""
form_obj = MyForm(request.POST) # 校验数据 post请求
# 4 判断数据是否合法
if form_obj.is_valid():
# 5. 如果合法,操作数据库存储数据
return HttpResponse('OK')
# 不合法, 错误信息展示到前
# 直接将该空对象传递给html页面
return render(request,'home.html', locals())
{% for form in form_obj %}
<p>
{{ form.label }}: {{ form }}
<span style="color: red">{{ form.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit">
"""
1. 必备条件 get请求和post请求传给html页面对象变量名必须一样
2. forms组件当你的数据不合法的情况下, 会保存你上次的数据
"""
class MyForm(forms.Form):
username = forms.CharField(min_length=3, max_length=8, label='用户名',
error_messages={
'min_length': '用户名至少三位',
'max_length': '用户名最大八位',
'required' : '用户名不能为空'
}
)
# username 最小三位 最大八位
password = forms.CharField(min_length=3, max_length=8, label='密码',
error_messages={
'min_length': '密码至少三位',
'max_length': '密码最大八位',
'required': '密码不能为空'
}
)
email = forms.EmailField(label='邮箱',
error_messages={
'invalid': '邮箱格式不正确',
'required': '邮箱不能为空'
}
)
钩子函数(HOOK)
"""
在特定的节点自动触发完成响应操作
钩子函数在forms组件中就类似于第二道关卡, 能够让我们自定义校验规则
在forms组件中有两类钩子
1.局部钩子
当你需要给某个字段增加校验规则的时候可以使用
2.全局钩子
当你需要给多个字段增加校验规则的时候可以使用
"""
eg:
"""
需求:
1. 校验用户名中不能含有666 只是校验username字段 使用局部钩子
2. 检验密码和确认密码是否一致 不是一个字段,用全局钩子
"""
class MyForm(forms.Form):
username = forms.CharField(min_length=3, max_length=8, label='用户名',
error_messages={
'min_length': '用户名至少三位',
'max_length': '用户名最大八位',
'required' : '用户名不能为空'
}
)
# username 最小三位 最大八位
password = forms.CharField(min_length=3, max_length=8, label='密码',
error_messages={
'min_length': '密码至少三位',
'max_length': '密码最大八位',
'required': '密码不能为空'
}
)
re_password = forms.CharField(min_length=3, max_length=8, label='确认密码',
error_messages={
'min_length': '确认密码至少三位',
'max_length': '确认密码最大八位',
'required': '确认密码不能为空'
}
)
email = forms.EmailField(label='邮箱',
error_messages={
'invalid': '邮箱格式不正确',
'required': '邮箱不能为空'
}
)
# email字段必须符合邮箱格式
# 钩子函数
# 局部钩子
def clean_username(self):
# 获取到用户名
username = self.cleaned_data.get('username')
if '666' in username:
# 提示前端展示错误信息
self.add_error('username', '用户名不能带有666')
# 将钩子函数构取来的数据放回去
return username
# 全局钩子
def clean(self):
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if not password == re_password:
self.add_error('re_password', '两次密码不一致')
return self.cleaned_data
label 字段名
error_messages 自定义报错信息
initial 设置默认值
required 控制字段是否必填
"""
字段没有样式:
针对不同类型的input如何修改
text
password
radio
checkbox
"""
widget=forms.PasswordInput(attrs={'class': 'form-control'}
# 多个属性值,,空格隔开就行
eg:widget=forms.PasswordInput(attrs={'class': 'form-control c1 c2 '}
eg:
password = forms.CharField(min_length=3, max_length=8, label='密码',
error_messages={
'min_length': '密码至少三位',
'max_length': '密码最大八位',
'required': '密码不能为空'
},widget=forms.PasswordInput(attrs={'class': 'form-control'})
)
# 第一道关卡里面支持正则校验
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
其他字段
phone = forms.CharField(
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
# 选择
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
# 单选Select
hobby = forms.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=3,
widget=forms.widgets.Select()
)
# 多选Select
hobby1 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
# 单选Checkbox
keep = forms.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
# 多选Checkbox
hobby2 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
cookie与session
cookie:
保存在浏览器上的信息都可以称之为cookie
它的表现形式一般都是kv键值对,可以有多个
session:
数据保存在服务端, 并且也是kv键值对
tooken:
session虽然数据是保存在服务端的,但是禁不住数据量大
服务端不在保存数据,而是在登录成功之后将一段信息加密处理(加密算法只有你公司的开发知道)
将加密之后的结果拼接在信息后面 整体返回给浏览器保存
浏览器下次访问的时候带着该信息 服务端自动切去前面一段信息在此使用自己的加密算法跟浏览器的密文进行比对
"""
总结:
cookie就是保存在客户端浏览器上面的kv键值对
session就是保存在服务器上面的kv键值对
session是基于cookie工作的(大部分保存用户状态的操作都需要使用的cookie)
"""