[Python自学] day-21 (2) (Cookie、FBV|CBV装饰器)

一、什么是Cookie

1.什么是Cookie?

Cookie是保存在客户端浏览器中的文件,其中记录了服务器让浏览器记录的一些键值对(类似字典)。

当Cookie中存在数据时,浏览器在访问网站时会读取属于自己的数据,并携带在请求中发送给服务器。

这种机制可以用于许多场景,例如用户登录。

Cookie非常重要,如果禁用了Cookie,大部分网站都不好用。

2.如何禁用Cookie

以Chrome为例:

进入设置--->高级--->隐私设置与安全性--->网站设置(或内容设置)--->Cookie和网站数据--->允许网站保存和读取Cookie数据(关闭)

[Python自学] day-21 (2) (Cookie、FBV|CBV装饰器)_第1张图片

 

3.关闭Cookie尝试登陆JD

[Python自学] day-21 (2) (Cookie、FBV|CBV装饰器)_第2张图片

 

在没有Cookie的情况下,会被提示"请再次登陆"或者"请您启用浏览器Cookie功能或更换浏览器"。

 

二、基于Cookie实现用户登录

1.实现登录页面mlogin.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Mgmt Logintitle>
    <link rel="stylesheet" href="/static/commons.css"/>
    <style>
        label{
            width: 80px;
            text-align: right;
            display: inline-block;
        }
        .error_span{
            color: red;
        }
    style>
head>
<body class="common">
    <form action="/mgmt/login/" method="post">
        <p>
            <label for="username">用户名:label>
            <input id="username" type="text" name="user"/>
            <span class="error_span">{{ user_error }}span>
        p>
        <p>
            <label for="password">密码:label>
            <input id="password" type="password" name="pwd"/>
            <input type="submit" value="提交"/>
            <span class="error_span">{{ pwd_error }}span>
        p>
    form>
    <script src="/static/jquery-1.12.4.js">script>
body>
html>

2.实现视图函数login()

def login(request):
    pwd_error_msg = ''
    # 当用户使用GET请求时,让其登录
    if request.method == "GET":
        return render(request, 'mlogin.html')
    if request.method == 'POST':
        username = request.POST.get('user', None)
        password = request.POST.get('pwd', None)
        dic = user_info.get(username)
        if not dic:
            # 用户不存在,重新登录
            pwd_error_msg = "用户不存在"
            return render(request, 'mlogin.html', {"pwd_error": pwd_error_msg})
        if dic['pwd'] == password:
            response = redirect('/mgmt/host')
            response.set_cookie('username', username)
            return response
        else:
            # 密码不正确,重新登录
            pwd_error_msg = "密码不正确"
            return render(request, 'mlogin.html', {"pwd_error": pwd_error_msg})

当账号密码验证成功时,向客户端写入cookie,并跳转到/mgmt/host页面。

3.定义映射关系

from django.contrib import admin
from django.urls import path
from django.urls import re_path

from mgmt import views

app_name = 'mgmt'
urlpatterns = [
    path('index/', views.index),
    re_path('host', views.host),
    re_path('login', views.login),
]

 

4.在host()视图函数中验证cookie

def host(request):
    # 如果是get请求,则将数据库中查询到的host列表和业务线列表返回,展示在页面上
    if request.method == 'GET':
        username = request.COOKIES.get('username')
        if not username:
            return redirect('/mgmt/login')
        host_list = models.Host.objects.all()
        busi_list = models.Business.objects.all()
        return render(request, 'host.html', {'username': username, 'host_list': host_list, 'busi_list': busi_list})
    elif request.method == 'POST':  # 当用户使用模态框添加主机时,使用表单POST提交
        # 获取表单提交的数据
        host = request.POST.get('hostname')
        ip = request.POST.get('ip')
        port = request.POST.get('port')
        # 这里的busi获取到的是select对应的busi_id
        busi = request.POST.get('busi_id')
        # 插入数据库
        models.Host.objects.create(
            hostname=host,
            ip=ip,
            port=port,
            busi_id=busi
        )
        # 重定向到host页面,以GET重新请求,页面就可以显示新的值
        return redirect('/mgmt/host')

如果没有cookie,则说明没有登录,跳转回login页面。如果有cookie,则显示登录用户名。

/mgmt/host页面的html代码和models代码参考:[Python自学] day-20 (Django-ORM、Ajax)

 

三、Cookie参数

1.Cookie失效时间

我们如果使用set_cookie('key',value)来设置Cookie,则Cookie会在关闭浏览器时失效。

有两种方式设置失效时间:

1)max_age参数(单位秒)

set_cookie('username', username, max_age=10)

这样设置以后,Cookie的有效时间就是10s,10s后刷新页面,就会跳转到登录页面(前提是写了这个跳转逻辑)。

2)expires参数(参数为datetime)

import datetime
now = datetime.datetime.utcnow()
delay = datetime.timedelta(10)
response.set_cookie('username', username, expires= now+delay)

同样设置以后,有效时间也是10s。

 

2.Cookie path、domain、secure、httponly参数

path参数:

当我们按前面章节的代码来添加Cookie的时候,Cookie是在所有页面都能访问的。

但是我们有可能需要在不同的页面访问不同的Cookie值,例如论坛的两个页面,一个页面(host页面)设置一页显示50条数据,另外一个页面(app)设置一页显示20条数据。

使用path参数:

set_cookie('show_num', 50, path='/')  # 所有页面
set_cookie('show_num', 50, path='/host')  # Host页面一页显示50条数据
set_cookie('show_num', 20, path='/app')  # App页面一页显示20条数据

domain参数:

用于设置cookie生效的域名。用于过滤生效范围。

secure参数:

如果使用的是https协议,则secure必须设置为Ture。

httponly参数:

如果httponly=True,则表示Cookie只能通过http协议传输,无法被JavaScript获取(不是绝对的,底层抓包可以获取到也可以被覆盖)

如果不设置,则在前端JS代码中可以使用以下代码获取cookie:

console.log(document.cookie)  //"username=leokale"

 

四、Cookie实现动态调整每页显示条目数

在  [Python自学] day-21 (1) (请求信息、html模板继承与导入、自定义模板函数、自定义分页) 中,我们实现了分页功能。效果如下:

[Python自学] day-21 (2) (Cookie、FBV|CBV装饰器)_第3张图片

 

 

每页默认显示10条数据。我们可以使用Cookie来实现动态调整每页显示条目数量。

1.在html中添加一个标签,提供用户每页显示数目的功能。

3)当页面加载完毕的时候,读取cookie是否存在per_page_count的值,如果没有,则默认为10,如果有,则设置在select标签中,确保显示与cookie一致。

4)当用户改变