十. 状态保持与表单
1.HttpsResponse 与 cookie
1.1 HttpResponse对象
1.2HTTPResponse的子类
返回数据的响应函数有:
- HttpResponse() 返回简单的字符串对象
- render() 渲染模板
- redirect() 重定向
- JsonResponse() 返回json数据
例:JsonResponse的用法
1.3Http协议理解
HTTP(超文本传输协议)是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。
1.4Cookie
1.浏览器中的Cookie
1.1 查找方式1
1.2 查找方式2
2.设置及获取cookie
注意:设置cookie值以及删除cookie值都是response对象的操作,而获取cookie是从requeset相应中获得的.
1.5 代码实现
1.5.1 设置cookie
1.在子应用的views文件设置显示函数
import datetime
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def set_ck(request):
#设置cookie
response = HttpResponse("设置cookie")
response.set_cookie('name','taka') # 没设置过期时间,默认关闭浏览器,cookie过期
#response.set_cookie('name1','taka1',max_age=120) # 设置过期是时间为120秒
#response.set_cookie('name2','taka2',expires=datetime.datetime(2028,8,6)) #设定过期日期
return response
2.在子应用的url文件设置路由
from django.urls import path,re_path
from .import views
urlpatterns = [
#设置cookie
path('set_ck',views.set_ck ,name = 'set_ck'),
]
3.运行结果
没设置过期时间,默认关闭浏览器,cookie过期
1.5.2 获取cookie
1.在子应用的views文件设置显示函数
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def delete_ck(request):
#删除cookie
response = HttpResponse('删除cookie')
response.delete_cookie('name')
return response
2.在子应用的url文件设置路由
from django.urls import path,re_path
from .import views
urlpatterns = [
#获取cookie
path('get_ck',views.get_ck ,name = 'get_ck'),
]
3.运行结果
1.5.3 删除cookie
1.在子应用的views文件设置显示函数
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def delete_ck(request):
#删除cookie
response = HttpResponse('删除cookie')
response.delete_cookie('name')
return response
2.在子应用的url文件设置路由
from django.urls import path,re_path
from .import views
urlpatterns = [
#删除cookie
path('delete_ck',views.delete_ck ,name = 'delete_ck'),
]
3.运行结果
删除cookie中的内容
2.session的状态保持
2.1什么是session
当浏览器第一次访问服务器时,服务器创建一个session对象(该对象有一个唯一的id,一般称之为sessionId),服务器会将sessionId以cookie的方式发送给浏览器。
当浏览器再次访问服务器时,会将sessionId发送过来,服务器依据sessionId就可以找到对应的session对象。
2.2 状态保持cookie和session
1.http协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态
2.客户端与服务器端的一次通信,就是一次会话实现状态保持的方式:在客户端或服务器端存储与会话有关的数据
3.存储方式包括cookie、session,会话一般指session对象
4. 使用cookie,所有数据存储在客户端,注意不要存储敏感信息
5.使用sesison方式,所有数据存储在服务器端,在客户端cookie中存储session_id
6状态保持的目的是在一段时间内跟踪请求者的状态,可以实现跨页面访问当前请求者的数据
- 注意:不同的请求者之间不会共享这个数据,与请求者一一对应
2.3 关于Session的使用前提
1. 在项目文件 settings.py文件中有INSTALLED_APPS 和 MIDDLEWARE 列表 ,其中包含Session的默认设置 例:
2.使用session之前需要先执行makemigrations,migrate的模型映射文件(迁移文件)命令,在数据库中有生成django_session的表格.
下面为之前建立模型实现模型迁移后,自动生成的django_session的文件
3. Session操作
3.1session基本操作
request.session['login'] = 'false' # 设置 session 中的数据
request.session.get('login') # 通过 key 来获取 session 中的数据
request.session.exists("login") # 判断 session 的 login 在数据库中是否存在
request.session.setdefault('login', 'false') # 为 session 的 key 设置默认值 false
del request.session['login'] # 删除 session 的 key 中的数据
request.session.delete() # 删除当前会话的所有 session 数据
request.session.flush() # 删除当前的 session 数据并删除 cookie
request.session.clear_expired() # 将所有过期的 session 数据删除
request.session.session_key # 会话 session 的 key
# 获取 session(字典) 中的所有 键、值、键值对
request.session.keys() # 提取所有键
request.session.values() # 提取所有值
request.session.items() # 提取所有键值对
request.session.iterkeys() # 迭代键
request.session.itervalues() # 迭代值
request.session.iteritems() # 迭代键值对
# 设置会话 session 和 cookie 的超时时间
request.session.set_expiry(value)
# 如果 value 是个整数 n,session 会在 n 秒后失效
# 如果 value 是个 datatime 或 timedelta,session 就会在这个时间后失效
# 如果 value 是 0,用户关闭浏览器 session 就会失效
# 如果 value 是 None,session 会依赖全局 session 失效策略
3.2在项目文件中的session.py中的session 配置
# 设置数据库 session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
# 设置缓存 session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是 memcache),此处别名依赖缓存的设置
# 设置文件 session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为 None,则使用 tempfile 模块获取一个临时地址 tempfile.gettempdir()
# 设置缓存、数据库 session
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
# 加密 cookie session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
3.3 Session的其他设置
SESSION_COOKIE_NAME = "sessionid" # session 的 cookie 保存在浏览器上时的 key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # session 的 cookie 保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # session 的 cookie 保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否用 https 传输 cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否 session 的 cookie 只支持 http 传输(默认)
SESSION_COOKIE_AGE = 1209600 # session 的 cookie 失效日期(2 个星期)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器的时候让 session 过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存 session,默认修改之后才保存(默认)
4.登录注册案例
4.1登录案例(无from表单引用)
1.设置登录模板home.html 与 login.html文件
home.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
你好,{{username}}<br>
<a href="{% url 'login'%}">登录</a><br>
<a href="{% url 'logout' %}">退出</a><br>
</body>
</html>
login.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<form method="post">
<!--跨域请求-->
{% csrf_token %}
<input type="text" name="username"/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
2.在子应用的views文件设置显示函数
import datetime
from django.shortcuts import render,redirect,reverse
from django.http import HttpResponse
# Create your views here.
def home(request):
#主页面
username = request.session.get('username', '未登录')
return render(request,'home.html',context={'username':username})
def login(request):
#登录页面
if request.method == 'GET':
#请求为get进入登录页面
return render(request,'login.html')
elif request.method == 'POST':
#请求为POST 则获取表单信息
username = request.POST.get('username')
# session 做状态保持,为了登陆以后用户名一直在上面
request.session['username'] = username
#设置会话过期时间
request.session.set_expiry(1200)
# 登录后重定向到home页面
return redirect(reverse('home'))
def logout(request):
#退出登录的逻辑
#1.退出登录的状态,状态在session里面
request.session.flush()
return redirect(reverse('home'))
3.在子应用的url文件设置路由
from django.urls import path,re_path
from .import views
urlpatterns = [
#主页,登录,退出
path('home',views.home ,name = 'home'),
path('login',views.login ,name = 'login'),
path('logout',views.logout ,name = 'logout'),
]
4.文件调用顺序
5.运行结果
5. from表单的引用
1. 什么是from表单
- 登录页面和注册页面都会用到form表单来提交数据
- 当数据提交到后台后,需要在视图函数中去验证数据的合法性.
- django中提供了一个form表单的功能,这个表单可以用来验证数据的合法性还可以用来生成HTML代码
今天的登录注册案例我们就来使用这个django自带的form来生成前端页面以及验证数据.
2.表单的使用
1. 创建一个forms.py的文件,放在指定的app当中,然后在里面写表单.
2. 表单是通过类实现的,继承自forms.Form,然后在里面定义要验证的字段.
3. 在表单中,创建字段跟模型是一模一样的,但是没有null=True或者blank=True等这几种参数了,有的参数是required=True/False.
4. 使用is_valid()方法可以验证用户提交的数据是否合法,而且HTML表单元素的name必须和django中的表单的name保持一致,否则匹配不到.
5. is_bound属性:用来表示form是否绑定了数据,如果绑定了,则返回True,否则返回False.
6. cleaned_data:这个是在is_valid()返回True的时候,保存用户提交上来的数据.
例:
3. form表单的参数
1.参数:
- max_length 最大长度
- min_length 最小长度
- widget 负责渲染网页上HTML 表单的输入元素和提取提交的原始数据
- attrs 包含渲染后的Widget 将要设置的HTML 属性
- error_messages 报错信息
2.参数应用代码示例
创建forms.py的文件,创建注册的表单:
from django import forms
class RegisterFrom(forms.Form):
username = forms.CharField(max_length=20,min_length=6)
password = forms.CharField(max_length=8,min_length=6,
widget=forms.PasswordInput(
attrs={'placeholder':'请输入密码'}),
error_messages={'min_length': '密码长度小于6',
'max_length': '密码长度超过8了'})
password_repeat = forms.CharField(widget=forms.PasswordInput())
email = forms.EmailField()
创建视图函数引用RegisterFrom表单
from .forms import RegisterFrom
from .models import UserModel
def register(request):
if request.method == 'GET':
form = RegisterFrom()
return render(request,'ts22/register.html',
context={'form':form})
elif request.method == 'POST':
form = RegisterFrom(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
password_repeat = form.cleaned_data.get('password_repeat')
email = form.cleaned_data.get('email')
if password == password_repeat:
user = UserModel.objects.create(username=username, password=password,email=email)
return HttpResponse('注册成功!')
else:
return HttpResponse('注册失败!')
else:
return HttpResponse('注册失败!')
4.代码实现
1.建立Form表单文件(forms.py)
from django import forms
class AddFrom(forms.Form):
first = forms.IntegerField(max_value=10)
second = forms.IntegerField(min_value=5)
2.建立模板 add_form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<form method="post">
{% csrf_token %}
{{form}}
<input type="submit" value="提交">
</form>
</body>
</html>
4.建立视图函数,要导入之前建立的form表单
from django.shortcuts import render,redirect,reverse
from django.http import HttpResponse
from .forms import AddFrom
# Create your views here.
def add_form(request):
if request.method == 'POST':
#提交表单数据
form = AddFrom(request.POST) # 得到表单数据,获取表单中post的数据
#对form表单的内容进行验证
if form.is_valid(): #如果表单的内容合法
#cleaned_data:这个是在is_valid()返回True的时候,保存用户提交上来的数据
a = form.cleaned_data['a']
b = form.cleaned_data['b']
return HttpResponse(str(int(a)) + str(int(b)))
else:
form = AddFrom() #如果校验不正确,重新填写表单
return render(request,'add_form.html',{'form':form})
5. 建立视图函数的url
from django.urls import path,re_path
from .import views
urlpatterns = [
# form表单
path('add_form',views.add_form ,name = 'add_form'),
]
6.实现结果