Python學習筆記整理總結【Django】:模板語言、分頁、Cookie、Session

1、模板語言 javascript

一、在前段展現:對象/字典/元組html

class Business(models.Model):
    # id   #用默認的自增id列    即:Business中有3列數據(id, caption, code)
    caption = models.CharField(max_length=32)
    code = models.CharField(max_length=32,default="SA")
#models.py
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.
def business(request):
    # 如下獲得的都是QuerySet類型數據(相似於列表)
    v1 = models.Business.objects.all()                                # ①獲得的是business obj對象  [obj(id,caption,code),obj(id,caption,code), ]
    v2 = models.Business.objects.all().values('id','caption')       # ②獲得的是字典              [{'id':1,'caption': '運維部'},{'id':1,'caption': '運維部'},...]
    v3 = models.Business.objects.all().values_list('id','caption')  # ③獲得的是元組              [(1,運維部),(2,開發)]
    return render(request, 'business.html', {'v1': v1,'v2': v2, 'v3': v3})
                                                                    #前端的三種形式:
                                                                        # {% for row in v %}
                                                                        #     ① <li>{{ row.id }} - {{ row.caption }} - {{ row.code }}</li>
                                                                        #     ② <li>{{ row.id }} - {{ row.caption }} - {{ row.code }}</li>
                                                                        #     ③ <li>{{ row.0 }} - {{ row.1 }} - {{ row.1 }</li>
                                                                        # {% endfor %}
#views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>業務線列表(對象)</h1>
    <ul>
        {% for row in v1 %}
            <li>{{ row.id }} - {{ row.caption }} - {{ row.code }}</li>
        {% endfor %}
    </ul>
    <h1>業務線列表(字典)</h1>
    <ul>
        {% for row in v2 %}
            <li>{{ row.id }} - {{ row.caption }}</li>
        {% endfor %}
    </ul>
    <h1>業務線列表(元組)</h1>
    <ul>
        {% for row in v3 %}
            <li>{{ row.0 }} - {{ row.1 }}</li>
        {% endfor %}
    </ul>
</body>
</html>
#business.html
from django.conf.urls import url
from django.contrib import admin

from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^business$', views.business), #加上終止符($)防止business匹配完成後如下的business_add再也不執行
]
#urls.py
INSTALLED_APPS = [
                    'app01',
                ]
#settings.py

二、排序
① forloop.counter 表示循環的次數,它從1開始計數,第一次循環設爲1前端

{% for item in todo_list %} 
    <p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
View Code

② forloop.counter0 表示循環的次數,它從0開始計數,第一次循環設爲0java

{% for item in todo_list %} 
    <p>{{ forloop.counter0 }}: {{ item }}</p>
{% endfor %}
View Code

③ forloop.revcounter  示循環中剩下的items數量,第一次循環時設爲items總數,最後一次設爲1jquery

{% for item in todo_list %} 
    <p>{{ forloop.revcounter }}: {{ item }}</p>
{% endfor %}
View Code

④ forloop.revcounter0 相似於forloop.revcounter,但它是表示的數量少一個,即最後一次循環時設爲0redis

{% for item in todo_list %} 
    <p>{{ forloop.revcounter0 }}: {{ item }}</p>
{% endfor %}
View Code

⑤ forloop.first 當第一次循環時值爲True,在特別狀況下頗有用)數據庫

{% for object in objects %} 
     {% if forloop.first %}<li class="first">{% else %}<li>{% endif %} 
     {{ object }} 
    </li>
{% endfor %}
View Code

⑥ forloop.last 當最後一次循環時值爲True django

{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
View Code

⑦ forloop.parentloop 在嵌套循環中表示父循環的forloop:後端

{% for country in countries %} 
    <table>
     {% for city in country.city_list %} 
        <tr>
            <td>Country #{{ forloop.parentloop.counter }} </td>
            <td>City #{{ forloop.counter }}</td>
            <td>{{ city }}</td>
        </tr>
     {% endfor %} 
    </table>
{% endfor %}
View Code

三、繼承
①模板繼承容許你創建一個基本的」骨架」模板, 它包含你全部最經常使用的站點元素 並 定義了一些能夠被子模板覆蓋的block。
注:一個html頁面只能繼承一個父模板,不能繼承多個瀏覽器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <style>
        .body-header{
            background-color: black;
        }
    </style>
</head>
<body>
#父模板(master.html)
{# 指定繼承的模板 #}
{% extends 'master.html' %}
 
{# 指定替換的位置 #}
{% block title %}
    tp1
{% endblock %}
 
{# 指定替換的位置 #}
 {% block content %}
    <p>tp1</p>
 {% endblock %}
#HTML頁面

②模板導入定製的組件include

<form>
    <input type="text" name="user"/>
    <input type="submit" value="提交"/>
</form>
#組件(tag.html)
{# 指定繼承的模板 #}
{% extends 'master.html' %}
 
{# 指定替換的位置 #}
{% block title %}
    tp1
{% endblock %}
 
{# 指定替換的位置 #}
{% block content %}
    <p>tp1</p>
 
    {# 導入單獨組件 #}
    {% include 'tag.html' %}
{% endblock %}
#HTML頁面

四、Simplelistfilter
有時候咱們須要在html上對後臺渲染的頁面進行二次處理,好比把字符串的首字母大寫、字符進行計算操做等。
(1)django默認自帶方法

{{ item.event_start|date:"Y-m-d H:i:s"}}    #日期格式進行轉換
{{ bio|truncatewords:"30" }}                  #取字符串前30位
{{ my_list|first|upper }}                     #第一個字符大寫             
{{ name|lower }}                                #全部字符小寫
View Code

(2)自定義simple_tag、filter
① 在app中建立templatetags文件夾
② templatetags中建立任意 .py 文件,如:handle.py

from django import template
from django.utils.safestring import mark_safe
 
register = template.Library()
 
@register.simple_tag()
def sub(a1,a2):    #能添加多個參數
    return a1 + a2
 
@register.filter()  
def lzl(a1,a2):    #只能傳入兩個參數
    return a1 + a2
#handle.py

③ 在settings中配置當前app,否則django沒法找到自定義的simple_tag

INSTALLED_APPS = (
          ......
    'cmdb',
)
#settings.py

④ 導入和使用simple_tag、filter

{# 導入py文件名 #}
{% load handle %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <div>{{ name|lower }}</div>
        <div>{{ name|upper }}</div>
 
        {% sub 1 2 %}
 
        {{ 'hello'|lzl:'world'}}
</body>
</html>
 
{#頁面內容#}
{#3 helloworld#}
#html

(3)django數據庫choice獲取字段

device_status_choices = (
        (1, '上架'),
        (2, '在線'),
        (3, '離線'),
        (4, '下架'),
    )
    device_type_id = models.IntegerField('設備類型',choices=device_type_choices, default=1)
 <td colspan="4">{{ response.data.asset.get_device_status_id_display }}</td>
View Code

 

 2、分頁 

一、簡單分頁
涉及xss攻擊,須要用到mark_safe方法,使用此方法字符串傳輸到後端後,已html形式顯示,而非字符串
分頁數進行定製,添加上一頁、下一頁,增長跳轉功能,實現分頁的完整功能 

  ① 設定每頁顯示數據條數
  ② 用戶輸入頁碼(第一頁、第二頁...)
  ③ 設定顯示多少頁號
  ④ 獲取當前數據總條數
  ⑤ 根據設定顯示多少頁號和數據總條數計算出,總頁數
  ⑥ 根據設定的每頁顯示條數和當前頁碼,計算出須要取數據表的起始位置
  ⑦ 在數據表中根據起始位置取值,頁面上輸出數據
  ⑧ 輸出分頁html,如:[上一頁][1][2][3][4][5][下一頁]

from app01 import views
urlpatterns = [
            .....
    url(r'^user_list/', views.user_list),
]
#urls.py
LIST = []
for i in range(109):
    LIST.append(i)

from django.utils.safestring import  mark_safe   #
def user_list(request):
    current_page = request.GET.get('p',1)  # 經過輸入p頁,利用get方法獲取當前頁碼。不輸入默認爲第1頁。獲得的是一個字符串。
    current_page = int(current_page)       # 把字符串 --> 數字

    start = (current_page-1)*10            # 起始頁
    end = current_page*10                  # 結束頁
    data = LIST[start:end]                 # 起始頁--結束頁的全部數據

    all_count = len(LIST)                  # 總數據個數
    total_count,y = divmod(all_count,10)   # 總頁面數,每頁多少條數據;divmod():整除,餘數
    if y :                                 # 存在餘數,總頁面數+1
        total_count +=1
    
    pager_num = 11                         # (顯示的)頁碼數
    page_list = []                         # 
    if total_count < pager_num :           # ①總頁面數 <(顯示的)頁碼數
        start_index = 1
        end_index = total_count + 1
    else:                                  # ②總頁面數 >=(顯示的)頁碼數
        if current_page <= pager_num/2:                      #【開頭】
            start_index = 1 # 首頁
            end_index = pager_num + 1
        elif current_page + (pager_num-1)/2 >= total_count:  #【中間】
            start_index = total_count - (pager_num-1)
            end_index = total_count + 1
        else:                                                #【結尾】
            start_index = current_page - (pager_num-1)/2
            end_index = current_page + (pager_num-1)/2 + 1 #最後一頁

    # 上下頁碼
    if current_page == 1:
        prev = '<a class="page" href="javascript:void(0)">上一頁</a>'  # 什麼都不幹
    else:
        prev =  '<a class="page" href="/user_list/?p=%s">上一頁</a>'%(current_page-1)
    page_list.append(prev)
    for i in range(int(start_index),int(end_index)):  #循環全部頁碼,選中的頁碼(當前頁)改變樣式,沒選中的不改變樣式
        if i == current_page:
            temp = '<a class="page active" href="/user_list/?p=%s">%s</a>'%(i,i)
        else:
            temp = '<a class="page" href="/user_list/?p=%s">%s</a>'%(i,i)

        page_list.append(temp)
    if current_page == total_count:
        nex = '<a class="page" href="javascript:void(0)">下一頁</a>'  # 什麼都不幹
    else:
        nex = '<a class="page" href="/user_list/?p=%s">下一頁</a>'%(current_page+1)
    page_list.append(nex)

    # 跳轉 能夠寫到前端
    jump = '''
    <input type="text" /><a onclick="jumpTo(this,'/user_list/?p=');">GO</a>
    <script>
        function jumpTo(ths,base) {
            var val = ths.previousSibling.value;
            location.href = base + val;
        }
    </script>
    '''
    page_list.append(jump)

    page_str = mark_safe(''.join(page_list))  # mark_safe(防止XSS攻擊,否側page_str傳到前端顯示的是字符串,而不是html語言)
                                              # 另外一種方式在前端作
                                              # {{ page_str|safe }}

                                              #(''.join(page_list)):將全部的頁碼以空字符串進行拼接
    return render(request,'user_list.html',{'li':data,'page_str':page_str})
#views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pagination .page{
            display: inline-block;
            padding: 5px;
            background-color: cyan;
            margin: 5px;
        }
        .pagination .page.active{
            background-color: brown;
            color: white;
        }
    </style>
</head>
<body>
    <ul>
        {% for item in li %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    <div class="pagination">
        {{ page_str }}
    </div>
</body>
</html>
#user_list.html

改進:頁碼代碼跟業務代碼分開,建立class類調用,最好單首創建目錄分開

from app01 import views
urlpatterns = [
            .....
    url(r'^user_list/', views.user_list),
]
#urls.py
LIST = []
for i in range(199):
    LIST.append(i)

class Page:
    def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):
        self.current_page = current_page
        self.data_count = data_count
        self.per_page_count = per_page_count
        self.pager_num = pager_num

    @property   # 利用屬性方法:把方法變成靜態屬性
    def start(self):
        return (self.current_page - 1) * self.per_page_count

    @property
    def end(self):
        return self.current_page * self.per_page_count

    @property
    def total_count(self):
        v, y = divmod(self.data_count, self.per_page_count)
        if y:
            v += 1
        return v

    def page_str(self, base_url):
        page_list = []

        if self.total_count < self.pager_num:   #self調用方法是不用加 ()
            start_index = 1
            end_index = self.total_count + 1
        else:
            if self.current_page <= (self.pager_num + 1) / 2:
                start_index = 1
                end_index = self.pager_num + 1
            else:
                start_index = self.current_page - (self.pager_num - 1) / 2
                end_index = self.current_page + (self.pager_num + 1) / 2
                if (self.current_page + (self.pager_num - 1) / 2) > self.total_count:
                    end_index = self.total_count + 1
                    start_index = self.total_count - self.pager_num + 1

        if self.current_page == 1:
            prev = '<a class="page" href="javascript:void(0);">上一頁</a>'
        else:
            prev = '<a class="page" href="%s?p=%s">上一頁</a>' % (base_url, self.current_page - 1,)
        page_list.append(prev)

        for i in range(int(start_index), int(end_index)):
            if i == self.current_page:
                temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i)
            else:
                temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i)
            page_list.append(temp)

        if self.current_page == self.total_count:
            nex = '<a class="page" href="javascript:void(0);">下一頁</a>'
        else:
            nex = '<a class="page" href="%s?p=%s">下一頁</a>' % (base_url, self.current_page + 1,)
        page_list.append(nex)

        jump = """
        <input type='text'  /><a onclick='jumpTo(this, "%s?p=");'>GO</a>
        <script>
            function jumpTo(ths,base){
                var val = ths.previousSibling.value;
                location.href = base + val;
            }
        </script>
        """ % (base_url,)

        page_list.append(jump)

        page_str = mark_safe("".join(page_list))

        return page_str
#pagination.py
from django.utils.safestring import  mark_safe
def user_list(request):
    current_page = request.GET.get('p', 1)
    current_page = int(current_page)
    page_obj = Page(current_page,len(LIST))

    data = LIST[page_obj.start:page_obj.end]

    page_str = page_obj.page_str("/user_list/")

    return render(request, 'user_list.html', {'li': data,'page_str': page_str})
#views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pagination .page{
            display: inline-block;
            padding: 5px;
            background-color: cyan;
            margin: 5px;
        }
        .pagination .page.active{
            background-color: brown;
            color: white;
        }
    </style>
</head>
<body>
    <ul>
        {% for item in li %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    <div class="pagination">
        {{ page_str }}
    </div>
</body>
</html>
#user_list.html

 

 

 

3、Cookie 

一、概述
Cookie,有時也用其複數形式 Cookies,指某些網站爲了辨別用戶身份、進行 session 跟蹤而儲存在用戶本地終端上的數據(一般通過加密)。(能夠叫作瀏覽器緩存:Cookie就是一段字符串,保存於本機電腦上。)
① 獲取Cookie

request.COOKIES['key']
request.COOKIES.get('key')
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    參數:
        default: 默認值
           salt: 加密鹽
        max_age: 後臺控制過時時間
#views.py

② 設置Cookie

rep = HttpResponse(...) 或 rep = render(request, ...) #return的對象
  
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密鹽',...)
    參數:
        key,              鍵
        value='',         值
        max_age=None,     超時時間 單位秒
        expires=None,     超時時間(IE requires expires, so set it if hasn't been already.) 單位日期
        path='/',         Cookie生效的路徑,/ 表示根路徑,特殊的:跟路徑的cookie能夠被任何url的頁面訪問 指定生效路徑
        domain=None,      Cookie生效的域名
        secure=False,     https傳輸改成True
        httponly=False    只能http協議傳輸,沒法被JavaScript獲取(不是絕對,底層抓包能夠獲取到也能夠被覆蓋)
 
補充:
# max_age 10秒失效
result.set_cookie('username',u,max_age=10)
 
# expires 設置失效日期
import datetime
current_date = datetime.datetime.utcnow()  # utcnow()當前時間
current_date = current_date + datetime.timedelta(seconds=5) # timedelta時間差
result.set_cookie('username',u,expires=current_date)
 
# 加密(帶簽名的)
obj = HttpResponse('s')
obj.set_signed_cookie('username',"kangbazi",salt="asdfasdf") #加密
request.get_signed_cookie('username',salt="asdfasdf")   # 解密

注:因爲cookie保存在客戶端的電腦上,因此,JavaScript和jquery也能夠操做cookie
<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });   #key vaule  字典
View Code

二、用戶登陸
利用cookie作用戶登陸頁面,只有登陸成功才能進入到後臺管理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>歡迎登陸:{{ current_user }}</h1>
</body>
</html>
#index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/login/" method="POST">
        <input type="text" name="username" placeholder="用戶名" />
        <input type="password" name="pwd" placeholder="密碼" />
        <input type="submit" />
    </form>
</body>
</html>
#login.html
user_info = {
    'solo':{'pwd':'123456'}
}
 
def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    if request.method == 'POST':
        u = request.POST.get('username')
        p = request.POST.get('pwd')
        dic = user_info.get(u)
        if not dic:
            return render(request,'login.html')
        if dic['pwd']== p:
            result = redirect('/index/')
            result.set_cookie('username',u)     #設置cookie值
            return result
        else:
            return render(request, 'login.html')
 
def index(request):
    v = request.COOKIES.get('username')         #獲取cookie值
    if not v :
        return redirect('/login/')
    return render(request,'index.html',{'current_user':v})
#views.py

三、定製分頁
根據用戶選擇的數字,顯示頁面的數量

<body>
    <ul>
        {% for item in li %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    <div>
        <select id='pg' onchange="ChangePageSize(this)">   #給選中的頁面增長一個事件
            <option value="10">10</option>
            <option value="30">30</option>
            <option value="50">100</option>
        </select>
    </div>
    <div class="pagination">
        {{ page_str }}
    </div>
    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>  #注意順序
    <script>
 
        $(function () {   # 頁面加載完成後執行此方法
            var v = $.cookie('per_page_count',{'path':'/user_list/'});#獲取選中的值,設置爲新一頁的默認值;路徑:只有當前頁面受影響
            $('#pg').val(v);
        });
 
        function ChangePageSize(ths) {
            var v = $(ths).val(); # 獲取用戶當前選擇的值
            $.cookie('per_page_count',v,{'path':'/user_list/'});
            location.reload()
        }
    </script>
</body>
#user_list.html
from django.utils.safestring import  mark_safe
def user_list(request):
    current_page = request.GET.get('p', 1)
    current_page = int(current_page)
 
    per_page_count = request.COOKIES.get('per_page_count',10)   #獲取cookie值
    per_page_count = int(per_page_count)
 
    page_obj = Page(current_page,len(LIST),per_page_count)
 
    data = LIST[page_obj.start:page_obj.end]
 
    page_str = page_obj.page_str("/user_list/")
 
    return render(request, 'user_list.html', {'li': data,'page_str': page_str})
# views.py

四、登陸認證(裝飾器)
①FBV

def auth(func):
    def inner(request,*args,**kwargs):
        v = request.COOKIES.get('username')  # 獲取cookie值
        if not v:
            return redirect('/login/')
        return  func(request,*args,**kwargs)
    return inner

@auth               #認證裝飾
def index(request):
    v = request.COOKIES.get('username')
    return render(request, 'index.html', {'current_user': v})
View Code

②CBV

def auth(func):
    def inner(request,*args,**kwargs):
        v = request.COOKIES.get('username')  # 獲取cookie值
        if not v:
            return redirect('/login/')
        return  func(request,*args,**kwargs)
    return inner

from django import views
from django.utils.decorators import method_decorator

@method_decorator(auth,name='dispatch')     #第一種方式
class Order(views.View):

    # @method_decorator(auth)                   #第二種方式
    # def dispatch(self, request, *args, **kwargs):
    #     return super(Order,self).dispatch(request, *args, **kwargs)

    # @method_decorator(auth)                   #單獨添加
    def get(self,reqeust):
        v = reqeust.COOKIES.get('username111')
        return render(reqeust,'index.html',{'current_user': v})

    def post(self,reqeust):
        v = reqeust.COOKIES.get('username111')
        return render(reqeust,'index.html',{'current_user': v})
View Code

 

3、Session   
一、概述
二者區別:Cookie是保存在用戶瀏覽器端的鍵值對,Session是保存在服務器端的鍵值對;Cookie作用戶驗證的時,敏感信息不適合放在Cookie中,別人能夠分析存放在本地的Cookie並進行Cookie欺騙,考慮到安全應當使用Session;用戶驗證時二者要結合使用,Session可保存到文件,內存,數據庫任意地方。 (session 保存於服務器,用來保存用戶的會話信息,依賴於Cookies)
① 獲取

# 獲取Session中數據
request.session['k1']
request.session.get('k1', None)
View Code

② 生成

# 生成Session中數據
request.session['k1'] = 123
request.session.setdefault('k1', 123)  # 存在則不設置
View Code

③ 刪除

# 刪除Session中某條數據
del request.session['k1']
 
# 刪除當前用戶的全部Session數據
request.session.delete("session_key")
request.session.clear()         #註銷時可用
View Code

④ 鍵值對

# 全部 鍵、值、鍵值對
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
View Code

⑤ 超時時間

# 設置超時時間
request.session.set_expiry(value)       #默認超時時間爲兩週
*若是value是個整數,session會在些秒數後失效。
*若是value是個datatime或timedelta,session就會在這個時間後失效。
*若是value是0, 用戶關閉瀏覽器session就會失效。
*若是value是None, session會依賴全局session失效策略。
View Code

⑥ 其餘

# 用戶session的隨機字符串
request.session.session_key
 
# 將全部Session失效日期小於當前日期的數據刪除
request.session.clear_expired()
 
# 檢查 用戶session的隨機字符串 在數據庫中是否 通常用不到
request.session.exists("session_key")
View Code

二、用戶登陸
利用Session作用戶登陸頁面,只有登陸成功才能進入到後臺管理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login/" method="post">
        <input type="text" name="user" />
        <input type="text" name="pwd" />
        <input type="checkbox" name="session" value="1"/> 保存1個月
        <input type="submit" value="提交" />
    </form>
</body>
</html>
#login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ request.session.username }}
</body>
</html>
#index.html
def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    elif request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'root' and pwd == "123":
            # 生成隨機字符串
            # 寫到用戶瀏覽器Cookie
            # 保存到Session中
            # 在隨機字符串對應的字典中設置相關內容...
            request.session['username'] = user
            request.session['if_login'] = True        #可不加 直接判斷username也能夠
            if request.POST.get('session') == '1':    #單獨設置超時時間,當前session生效,不影響全局
                request.session.set_expiry(10)        #10秒
            return redirect('/index/')
        else:
            return redirect('/login/')
 
def index(request):
    # 獲取當前用戶的隨機字符串
    # 根據隨機字符串獲取對應信息
    if request.session.get('if_login'):
        return render(request, 'index.html')
    else:
        return redirect('/login/')
#vars.py

三、Django中默認支持Session,其內部提供了5種類型的Session供開發者使用:
①數據庫Session(默認)

Django默認支持Session,而且默認是將Session數據存儲在數據庫中,即:django_session 表中。
 
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默認)
     
    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,默認修改以後才保存(默認)
 
 
b. 使用
 
    def index(request):
        # 獲取、設置、刪除Session中數據
        request.session['k1']
        request.session.get('k1',None)
        request.session['k1'] = 123
        request.session.setdefault('k1',123) # 存在則不設置
        del request.session['k1']
 
        # 全部 鍵、值、鍵值對
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()
 
        # 用戶session的隨機字符串
        request.session.session_key
        # 將全部Session失效日期小於當前日期的數據刪除
        request.session.clear_expired()
        # 檢查 用戶session的隨機字符串 在數據庫中是否
        request.session.exists("session_key")
        # 刪除當前用戶的全部Session數據
        request.session.delete("session_key")
 
        request.session.set_expiry(value)
            * 若是value是個整數,session會在些秒數後失效。
            * 若是value是個datatime或timedelta,session就會在這個時間後失效。
            * 若是value是0,用戶關閉瀏覽器session就會失效。
            * 若是value是None,session會依賴全局session失效策略。
View Code

②緩存存儲Session
能夠設置爲Memcache緩存,默認不支持redis(可使用網上插件)

#本地內存存儲session
配置settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'            # 使用的緩存別名(默認內存緩存,也能夠是memcache),此處別名依賴緩存的設置

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,默認修改以後才保存

#Memcache緩存
配置settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'db'  # 使用的緩存別名,此處別名依賴緩存的設置

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11211',
        ]
    },
    'db': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11211',
        ]
    }
}
View Code

③文件存儲Session

#文件session
配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir()                                                            # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
 
 
    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,默認修改以後才保存
View Code

④緩存+數據庫Session

#緩存+數據庫Session
數據庫用於作持久化,緩存用於提升效率,先去緩存中取數據,緩存沒有再去數據庫中取,而後在緩存中存一份

配置settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'  # 引擎
View Code

⑤加密cookie Session

#加密cookie Session
數據都存在於客戶端
配置settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'  # 引擎
#注:當使用Session時,須要執行makemigrations和 migrate,數據庫上會自動生成django_session數據表
View Code

Session&Cookie 總結

Cookie就是一段字符串,保存於本機電腦上。
session 保存於服務器,用來保存用戶的會話信息,依賴於Cookies

流程:舉個例子,我們在登陸一個網站後,拿JD舉例,若是我登陸進去以後,在想點擊訂單的時候。server斷怎麼判斷我是「我」,而不是其餘人呢?
Http是短鏈接,那麼Server端確定有一個保存我登陸狀態的地方(session),那server怎麼判斷是我發送過來的請求呢?就是經過Cookie!
當客戶端訪問過來後,server端會在IE裏生成一個Cookie,當訪問過來的時候就能夠經過Cookie進行判斷

在session中,咱們能夠設置多個key:value的值,咱們能夠在session設置,當用戶登陸的時候,咱們把的用戶名,增長到session中,那麼用戶攜帶cookie訪問的時候,咱們就能判斷是哪一個一用來訪問的!

Session和Cookie好處:Cookie能夠理解爲一個身份證ID,你只能拿着他去和Server端進行通訊,若是你沒有這個ID那麼server端也不知道你是誰!(我在寫博客的時候在作Cookie和Session的實驗,把Cookie刪掉了!當我保存的時候直接給我提出來了,爲何呢?就是由於,server端不知道我是誰了,我已經沒有密鑰了。)

因此,只要Session和Cookie任意一方失效,就能夠理解爲:Cookie失效就至關於身份證ID過時,須要從新認證才能夠繼續使用。Session失效就至關於銀行裏的數據標識此ID無效,也須要從新申請。

相關文章
相關標籤/搜索