首页 > 其他 > 详细

django之forms组件,cookie&session

时间:2019-06-16 00:19:19      阅读:107      评论:0      收藏:0      [点我收藏+]

forms组件

先自己实现注册功能,并且对用户输入的信息加限制条件
如果用户输入的信息不符合条件,前端展示报错信息
技术分享图片
 1 from django.shortcuts import render,HttpResponse
 2 
 3 
 4 from django.core.exceptions import ValidationError
 5 # Create your views here.
 6 
 7 
 8 
 9 def register(request):
10     errors = {name:‘‘, pwd:‘‘}  #定义一个字典,将字典传给前端,前端是可以取值的
11     if request.method == POST:
12         name = request.POST.get(name)
13         pwd = request.POST.get(pwd)
14         if sb in name:
15             errors[name] =名字不能包含sb
16         if pwd == 123:
17             errors[pwd] = 你这密码太简单了
18     return render(request,reg.html,locals())
Views.py
技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <h3>注册页面</h3>
 9 
10 <form action="" method="post">
11     <p>username:<input type="text" name="name">
12         <span>{{ errors.name }}</span>  <!--span是行内标签,大小由文本决定的,如果取到的值为空前端展示到前端页面看不出-->
13     </p>
14 
15     <p>password:<input type="text" name="pwd">
16     <span>{{ errors.pwd }}</span></p>
17     <input type="submit">
18 </form>
19 
20 </body>
21 </html>
reg.html

注意:reg.html中的

<span>{{ errors.name }}</span>

思路:访问路由,是get请求然后error字典中的value值为空,所以传入前端的error信息为空,
然后span标签是根据文本内容的大小来撑大,所以没有内容就不变,不会有什么影响,
第二次form表单提交的时候是有name和password的数据,
然后进行校验,如果不满足条件,就给error字典赋值传给前端,所以前端会显示错误信息
总结:
注册示例:
1.前端渲染标签获取用户输入 >>> 前端渲染标签
2.后端获取用户输入,进行数据校验 >>> 数据校验
3.校验过后产生的提示信息返回给前端 >>> 展示校验信息

提一小嘴:??‍♀?
数据校验:
前端后端都必须做数据校验,前端不做问题不大,后端必须要做!(防爬虫!!!) (提前low一眼哈哈哈)??????(前端浏览器会自动做校验)
技术分享图片
form组件就能帮我们完成上面的三步:???
1.生成前端html代码
2.校验数据
3.展示校验信息
先上图看看前端的效果??
技术分享图片
forms组件的使用??
1.简单的form组件校验数据
校验数据
1.得写一个forms校验的类
from django import forms
class RegForm(forms.Form):
# forms组件中定义的字段,默认都是必须传值的
name = forms.CharField(max_length=6)
pwd = forms.CharField(max_length=8,min_length=3)
email = forms.EmailField()
2.实例化RegForm传值
# 注意传入的字典的key必须跟类里面的变量名一致,校验的数据可以多传,但是不能少传
res = views.RegForm({‘name‘:‘dsb‘,‘pwd‘:‘123‘,‘email‘:‘123@qq.com‘})
3.数据是否合法
res.is_valid() # 如果数据全部校验通过才为True否则均为False
4.查看校验通过的数据
res.cleaned_data # 会将校验通过的数据都放入cleaned_data中
5.查看校验失败的数据
res.errors # 会将校验失败的数据的提示信息都放入errors中
"""
{
‘name‘: [‘Ensure this value has at most 6 characters (it has 7).‘],
‘pwd‘: [‘Ensure this value has at least 3 characters (it has 2).‘]
}
"""
几个图例看看更清楚哦??
技术分享图片技术分享图片
??????????
技术分享图片
??????
技术分享图片
??????
技术分享图片
??????
技术分享图片
??????
技术分享图片

forms渲染标签

渲染标签
form组件值渲染获取用户输入(或选择的...只要是用户操作都算)的标签
提交按钮需要我们自己手动写

三种方式:
1.{{ form_obj.as_p }}
2.{{ form_obj.name.label }}{{ form_obj.name }}
3.{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}

技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <p>第一种渲染方式(封装程度太高,没法做扩展,不推荐使用,了解即可)</p>
10 {{ form_obj.as_p }} <!--渲染成一个个p标签-->
11 {{ form_obj.ul }}   <!--渲染成一个个ul标签-->
12 
13 
14 <p>第二种渲染方式</p>
15 <form action="">
16     <p>{{ form_obj.name.label }}{{ form_obj.name }}</p>
17     <p>{{ form_obj.pwd.label }}{{ form_obj.pwd }}</p>
18     <p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
19     <input type="submit">
20 </form>
21 
22 <p>第三种渲染方式</p>
23 <form action="">
24     {% for foo in form_obj %}
25     <p>{{ foo.label }}{{ foo }}</p>
26     {% endfor %}
27 
28 </form>
29 
30 </body>
31 </html>
reg.html
<!--渲染成一个个ul标签-->
{{ form_obj.ul }}  

技术分享图片

{{ form_obj.as_p }} <!--渲染成一个个p标签-->

技术分享图片

<p>第二种渲染方式</p>
<form action="">
<p>{{ form_obj.name.label }}{{ form_obj.name }}</p>
<p>{{ form_obj.pwd.label }}{{ form_obj.pwd }}</p>
<p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
<input type="submit">
</form>



<p>第三种渲染方式</p>
<form action="">
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}

</form>
以下图片有误,是第三种渲染方式

技术分享图片

展示报错信息??

 

<form action="" method="post" novalidate>
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
<span>{{ foo.errors.0 }}</span> <!--errors是多个参数,代表是多个参数,就用ul套li的形式展示出来,.0是取报错信息本身文本,而不是取我报错信息对象-->
{% endfor %}
<input type="submit">
</form>

技术分享图片

 

技术分享图片

 

技术分享图片

 

forms组件局部钩子,全局钩子

#钩子函数
#局部钩子
#如想给name字段额外的校验, (会先从上往下走,三个字段将原本定义好的先校验一遍,再来走这个局部校验)
def clean_name(self):
name = self.cleaned_data.get(‘name‘)
if ‘666‘ in name:
#两种方式,手动添加
self.add_error(‘name‘,‘不能包含666‘)
# 抛异常
# raise ValidationError(‘不能包含666‘) #需要导入(在上头)from django.core.exceptions import ValidationError
else:
#拿出来校验的数据必须返回去
return name
#全局钩子 (将cleaned_data中的所有数据都交给你了,所以你做完校验之后都还给我,你不还给我就没了,再后面函数使用的时候就是空的)
#用于密码确认,
def clean(self):
pwd = self.cleaned_data.get(‘pwd‘)
confirm_pwd = self.cleaned_data.get(‘confirm_pwd‘)
if pwd == confirm_pwd:
return self.cleaned_data
else:
self.add_error(‘confirm_pwd‘,‘两次棉麻不一致‘) #全局要把报错信息加进去,不能使用抛异常的方法
总的代码过一遍
技术分享图片
  1 from django.shortcuts import render,HttpResponse
  2 
  3 
  4 from django.core.exceptions import ValidationError
  5 # Create your views here.
  6 
  7 
  8 
  9 def register(request):
 10     errors = {name:‘‘, pwd:‘‘}  #定义一个字典,将字典传给前端,前端是可以取值的
 11     if request.method == POST:
 12         name = request.POST.get(name)
 13         pwd = request.POST.get(pwd)
 14         if sb in name:
 15             errors[name] =名字不能包含sb
 16         if pwd == 123:
 17             errors[pwd] = 你这密码太简单了
 18     return render(request,reg.html,locals())
 19 
 20 from django import forms
 21 class RegForm(forms.Form):  #forms校验三个字段属性,只要有一条不符合就返回false
 22     #forms组件中定义的字段,默认都是必须传值的
 23     name = forms.CharField(max_length=8,label=用户名,error_messages={
 24         max_length:用户名最长只能6位,
 25     required:这个字段不能为空},widget=forms.TextInput())  #没写默认采用Name作为label
 26     pwd = forms.CharField(max_length=8, min_length=3,error_messages={
 27         max_length:密码最长8位,
 28         min_length:密码最短3位,
 29         required:密码这个字段不能为空,
 30         #attrs={‘class‘:‘c1‘ ‘form-control‘} 修改样式:c1是input框继承的类
 31     },widget=forms.widgets.PasswordInput(attrs={class:c1 form-control}))  #最小三位   widget=forms.widgets.PasswordInput()密码是密文显示
 32 
 33     #注册还需要确认密码
 34     confirm_pwd = forms.CharField(max_length=8, min_length=3, error_messages={
 35         max_length: 密码最长8位,
 36         min_length: 密码最短3位,
 37         required: 密码这个字段不能为空,
 38         # attrs={‘class‘:‘c1‘ ‘form-control‘} 修改样式:c1是input框继承的类
 39     }, widget=forms.widgets.PasswordInput(attrs={class: c1 form-control}))
 40 
 41 
 42     email = forms.EmailField(label=邮箱,error_messages={
 43         invalid:邮箱格式不正确,
 44         required: 邮箱这个字段不能为空,
 45     })
 46 
 47     gender = forms.ChoiceField(
 48         choices=((1, ), (2, ),(3,保密)),
 49         label = 性别,
 50         initial = 3,
 51         widget=forms.widgets.RadioSelect()
 52     )
 53 
 54     #钩子函数
 55     #局部钩子
 56     #如想给name字段额外的校验, (会先从上往下走,三个字段将原本定义好的先校验一遍,再来走这个局部校验)
 57     def clean_name(self):
 58         name = self.cleaned_data.get(name)
 59         if 666 in name:
 60             #两种方式,手动添加
 61             self.add_error(name,不能包含666)
 62             # 抛异常
 63             # raise ValidationError(‘不能包含666‘)  #需要导入(在上头)from django.core.exceptions import ValidationError
 64         else:
 65             #拿出来校验的数据必须返回去
 66             return name
 67     #全局钩子 (将cleaned_data中的所有数据都交给你了,所以你做完校验之后都还给我,你不还给我就没了,再后面函数使用的时候就是空的)
 68     #用于密码确认,
 69     def clean(self):
 70         pwd = self.cleaned_data.get(pwd)
 71         confirm_pwd = self.cleaned_data.get(confirm_pwd)
 72         if pwd == confirm_pwd:
 73             return self.cleaned_data
 74         else:
 75             self.add_error(confirm_pwd,两次棉麻不一致)  #全局要把报错信息加进去,不能使用抛异常的方法
 76 
 77 
 78 def reg(request):
 79     #实例化一个form对象
 80     form_obj = RegForm()
 81     return render(request, reg1.html,locals())
 82 def reg2(request):
 83     #实例化一个form对象
 84     form_obj = RegForm()
 85     if request.method == POST:
 86         print(request.POST)
 87         # < QueryDict: {‘name‘: [‘dsb‘], ‘pwd‘: [‘123‘], ‘email‘: [‘123@qq.com‘]} >
 88         form_obj = RegForm(request.POST)  #因为是字典可以直接传给RegForm
 89         #需要注意的是:前端的input name的属性必须跟form组件种的字段名一致
 90         if form_obj.is_valid():
 91             return HttpResponse(ok)
 92     return render(request, reg2.html,locals())
 93 
 94 #第一次form_obj = RegForm实例化的时候没传值,没有做校验,所以给前端页面的是一个空字典,只有渲染页面的效果
 95 #第二次 form_obj = RegForm(request.POST) ,POST请求来了有数据传输过来,进行校验,所以可以form_obj.is_valid()
 96 from app01 import models
 97 def reg3(request):
 98     #实例化一个form对象
 99     form_obj = RegForm()
100     if request.method == POST:
101         print(request.POST)
102         # < QueryDict: {‘name‘: [‘dsb‘], ‘pwd‘: [‘123‘], ‘email‘: [‘123@qq.com‘]} >
103         form_obj = RegForm(request.POST)  #因为是字典可以直接传给RegForm
104         #需要注意的是:前端的input name的属性必须跟form组件种的字段名一致
105         if form_obj.is_valid():
106             models.User.objects.create(**form_obj.cleaned_data) #form配合models用,其实是为了models服务的,只是保存数据
107     return render(request, reg2.html,locals())
Views.py
技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <h3>注册页面</h3>
 9 
10 <form action="" method="post">
11     <p>username:<input type="text" name="name">
12         <span>{{ errors.name }}</span>  <!--span是行内标签,大小由文本决定的,如果取到的值为空前端展示到前端页面看不出-->
13     </p>
14 
15     <p>password:<input type="text" name="pwd">
16     <span>{{ errors.pwd }}</span></p>
17     <input type="submit">
18 </form>
19 
20 </body>
21 </html>
reg.html
技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <p>第一种渲染方式(封装程度太高,没法做扩展,不推荐使用,了解即可)</p>
10 {{ form_obj.as_p }} <!--渲染成一个个p标签-->
11 {{ form_obj.ul }}   <!--渲染成一个个ul标签-->
12 
13 
14 <p>第二种渲染方式</p>
15 <form action="">
16     <p>{{ form_obj.name.label }}{{ form_obj.name }}</p>
17     <p>{{ form_obj.pwd.label }}{{ form_obj.pwd }}</p>
18     <p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
19     <input type="submit">
20 </form>
21 
22 <p>第三种渲染方式</p>
23 <form action="">
24     {% for foo in form_obj %}
25     <p>{{ foo.label }}{{ foo }}</p>
26     {% endfor %}
27 
28 </form>
29 
30 </body>
31 </html>
reg1.html
技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <form action="" method="post" novalidate>
 9     {% for foo in form_obj %}
10     <p>{{ foo.label }}{{ foo }}</p>
11         <span>{{ foo.errors.0 }}</span> <!--errors是多个参数,代表是多个参数,就用ul套li的形式展示出来,.0是取报错信息本身文本,而不是取我报错信息对象-->
12     {% endfor %}
13     <input type="submit">
14 </form>
15 </body>
16 </html>
reg2.html

forms组件扩展字段

技术分享图片
 1     gender = forms.ChoiceField(
 2         choices=((1, ""), (2, ""), (3, "保密")),
 3         label="性别",
 4         initial=3,
 5         widget=forms.widgets.RadioSelect()
 6     )
 7     hobby = forms.ChoiceField(
 8         choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
 9         label="爱好",
10         initial=3,
11         widget=forms.widgets.Select()
12     )
13     hobby1 = forms.MultipleChoiceField(
14         choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
15         label="爱好",
16         initial=[1, 3],
17         widget=forms.widgets.SelectMultiple()
18     )
19     keep = forms.ChoiceField(
20         label="是否记住密码",
21         initial="checked",
22         widget=forms.widgets.CheckboxInput()
23     )
24     hobby2 = forms.MultipleChoiceField(
25         choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
26         label="爱好",
27         initial=[1, 3],
28         widget=forms.widgets.CheckboxSelectMultiple()
29     )
Views.py

技术分享图片

cookie

本质:保存在浏览器上的键值对 
用途:标识当前用户信息
cookie是服务端设置的,浏览器可以选择禁用
设置Cookie
问题:django返回的信息都是什么对象?
HttpResponse对象

return render()
return HttpResponse()
return redirect()


res1 = render()
return res1
res2 = HttpResponse()
return res2
res3 = redirect()
return res3
设置Cookie
需要通过HttpResponse对象来设值
res1 = render()
res1.set_cookie(‘name‘,‘jason‘)
return res1
获取Cookie
request.COOKIES[‘key‘]
request.COOKIES.get(‘key‘)

session

本质:保存在服务器上的键值对
用途:记录当前用户信息
session其实也是基于cookie工作的
为了数据更加安全,给浏览器存一个随机字符串,将用户信息存在服务端,
sessionid:‘随机字符串‘
用户在访问的时候,拿着这个随机字符串来后端进行匹配
设置Session  (django 默认的session过期时间是14天)
request.session[‘k1‘] = 123
# 上面这句话干了三件事
# 1.内部自动生成一个随机字符串 一个浏览器对应一个
# 2.将随机字符串与数据字典存入django session表中
# 3.将随机字符串设置到浏览器的cookie中

获取session
request.session.get(‘k1‘)
# 浏览器将随机字符串发送给服务端之后,服务端自动拿着随机字符串去
# django_session表查找改字符串所对应的value(大字典),如果匹配成功会将这个value赋值给request.session
# 如果没有,说明当前用户没有进行身份认证.建议使用request.session.get()来获取大字典

删除session
# 删除当前会话的所有Session数据
request.session.delete() # 只删django_session表里的数据
  
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush() # 表和浏览器的session都删除
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。

# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value) # value值同cookie设置超时时间
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。

session数据是存放在服务器端的数据库中
数据库可以有多种选择

Cookie和Session??
http协议不保存用户状态(信息)
Cookie和Session都是为了能够保存用户信息
技术分享图片
 1 from django.shortcuts import render,HttpResponse,redirect
 2 
 3 # Create your views here.
 4 
 5 from functools import wraps
 6 def login_auth(func):
 7     @wraps(func)
 8     def inner(request,*args, **kwargs):
 9         path = request.get_full_path()
10         print(path)
11         if request.COOKIES.get(name):
12             return func(request, *args, **kwargs)
13         else:
14             return redirect(/login?next=%s%path)
15     return inner
16 
17 
18 
19 @login_auth
20 def login(request):
21     if request.method == POST:
22         username = request.POST.get(username)
23         password = request.POST.get(password)
24         if username == egon and password == 123:
25             old_path = request.GET.get(next)
26             if old_path:
27                 obj = redirect(old_path)
28             else:
29                 obj = redirect(/index)
30             obj.set_cookie(name,egon,max_age=1)
31             return obj
32     return render(request, login.html)
33 
34 @login_auth
35 def index(request):
36     # if request.COOKIES.get(‘name‘):
37     #     return HttpResponse(‘我是index页面,只有登录了才能看‘)
38     return HttpResponse(index)
39 
40 @login_auth
41 def home(request):
42     return HttpResponse(home)
43 
44 @login_auth
45 def order(request):
46     return HttpResponse(home)
47 
48 
49 def logout(request):
50     res = redirect(/login)
51     res.delete_cookie(name)
52     return res
53 
54 
55 def set_session(request):
56     #设置键值对
57     request.session[gender] = hasdhsjka
58     #上面这句话干了这三件事
59     #1.内部自动生成一个随机字符串,一个浏览器对应一个
60     #2.将随机字符串与数据字典存入django session表中
61     #3.将随机字符串设置到浏览器的cookie中
62     return HttpResponse(ok)
63 
64 def get_session(request):
65     print(request.session.get(gender))
66     return HttpResponse(ok)
Views.py
技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <form action="" method="post">
 9     <p>username:<input type="text" name="username"></p>
10     <p>password:<input type="text" name="password"></p>
11     <input type="submit">
12 </form>
13 </body>
14 </html>
login.html

 

django之forms组件,cookie&session

原文:https://www.cnblogs.com/huangxuanya/p/11029135.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!