python Django session/cookie


一, Cookie

#cookie
# def cook1(request):
#     print(request.COOKIES) # 查看cooke
#     # print(request.get_signed_cookie('k2',salt='uuu'))
#     rep = HttpResponse('ok')  # 設置cook 必須在響應里面設置
#     # rep.set_cookie('k1',123) # 普通的cooke
#     # rep.set_signed_cookie('k2',666,salt='uuu') # 加密的cookie salt加嚴
#     #
#     rep.set_cookie('k999',123,path='/cooke1/') # 添加路徑表示只有在當前url下才會生效
#     rep.set_cookie('k888',123)
#     return rep
# def cook2(request):
#     print(request.COOKIES) # 查看cooke
#     rep = HttpResponse('ok')
#     return rep

1、獲取Cookie:

1 request.COOKIES['key']
2 request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
3     參數:
4         default: 默認值
5            salt: 加密鹽
6         max_age: 后台控制過期時間

2、設置Cookie:

 1 rep = HttpResponse(...) 或 rep = render(request, ...)
 2  
 3 rep.set_cookie(key,value,...)
 4 rep.set_signed_cookie(key,value,salt='加密鹽',...)
 5     參數:
 6         key,              鍵
 7         value='',         值
 8         max_age=None,     超時時間
 9         expires=None,     超時時間(IE requires expires, so set it if hasn't been already.)
10         path='/',         Cookie生效的路徑,/ 表示根路徑,特殊的:跟路徑的cookie可以被任何url的頁面訪問
11         domain=None,      Cookie生效的域名
12         secure=False,     https傳輸
13         httponly=False    只能http協議傳輸,無法被JavaScript獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋)

由於cookie保存在客戶端的電腦上,所以,JavaScript和jquery也可以操作cookie。

1 <script src='/static/js/jquery.cookie.js'></script>
2 $.cookie("list_pager_num", 30,{ path: '/' });

Session

Django中默認支持Session,其內部提供了5種類型的Session供開發者使用:

  • 數據庫(默認)
  • 緩存
  • 文件
  • 緩存+數據庫
  • 加密cookie

1、數據庫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")
 
        ...

2、緩存Session

a. 配置 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,默認修改之后才保存
 
 
 
b. 使用
 
    同上

3、文件Session

a. 配置 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,默認修改之后才保存
 
b. 使用
 
    同上

4、緩存+數據庫Session

數據庫用於做持久化,緩存用於提高效率
 
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
 
b. 使用
 
    同上

5、加密cookie Session

a. 配置 settings.py
     
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
 
b. 使用
 
    同上

擴展:Session用戶驗證

def login(func):
    def wrap(request, *args, **kwargs):
        # 如果未登陸,跳轉到指定頁面
        if request.path == '/test/':
            return redirect('http://www.baidu.com')
        return func(request, *args, **kwargs)
    return wrap

 csrf 跨站請求偽造

一、簡介

django為用戶實現防止跨站請求偽造的功能,通過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成。而對於django中設置防跨站請求偽造功能有分為全局和局部。

全局:

  中間件 django.middleware.csrf.CsrfViewMiddleware

局部:

  • @csrf_protect,為當前函數強制設置防跨站請求偽造功能,即便settings中沒有設置全局中間件。
  • @csrf_exempt,取消當前函數防跨站請求偽造功能,即便settings中設置了全局中間件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

csrf :
 Django 有兩種 :全局配置和 裝飾器
    默認的是全局配置:
            settings 中設置了'django。middleware.csrf.CsrfViewMiddleware'
                    必須遵循規則 {% csrf_token%}
                                    views: render
                    
                    如果 某一個函數上添加了 裝飾器 @csrf_exempt 那么它就會失效 不必遵循以上規則
            
            去掉' django。middleware.csrf.CsrfViewMiddleware' 時
                    所有的地方都失效
                    
                    如果非要在一個地方用到csrf
                    
                    可以加上裝飾器 @csrf_protoct
                            則要必須遵循規則 {% csrf_token%}
                                            views: render
                                            
            csrftoken存在於兩個地方 瀏覽器 和 cookie 中        

二、應用

1、普通表單

veiw中設置返回值:
  return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))  
     或者
     return render(request, 'xxx.html', data)
  
html中設置Token:
  {% csrf_token %}

2、Ajax

對於傳統的form,可以通過表單的方式將token再次發送到服務端,而對於ajax的話,使用如下方式。

view.py

from django.template.context import RequestContext
# Create your views here.
  
  
def test(request):
  
    if request.method == 'POST':
        print request.POST
        return HttpResponse('ok')
    return  render_to_response('app01/test.html',context_instance=RequestContext(request))

text.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    {% csrf_token %}
  
    <input type="button" onclick="Do();"  value="Do it"/>
  
    <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
    <script src="/static/plugin/jquery/jquery.cookie.js"></script>
    <script type="text/javascript">
        var csrftoken = $.cookie('csrftoken');
  
        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });
        function Do(){
  
            $.ajax({
                url:"/app01/test/",
                data:{id:1},
                type:'POST',
                success:function(data){
                    console.log(data);
                }
            });
  
        }
    </script>
</body>
</html>
+

 Form驗證

django中的Form一般有兩種功能:

  • 輸入html-----------不能你自己寫一些標簽,而幫你自動生成
  • 驗證用戶輸入-------將用戶驗證信息保存起來,可以傳到前段
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.shortcuts import render,HttpResponse
from app.froms import Form1
from app import models
def form1(request):
    if request.method == 'POST':
        # request.POST.get('user',None)
        # request.POST.get('pwd',None)
        f1 = Form1(request.POST)  #request.POST用於獲取數據,這里的f1和下面的f2不一樣,這里有參數可以獲取錯誤信息
        if f1.is_valid():
            print(f1.cleaned_data)#驗證成功,獲取用戶信息
        else:
            print(f1.errors)  # 驗證錯誤,獲取錯誤信息
            return render(request,'account/from.html',{'f':f1})
    else:
        f2 = Form1()  #這里的f2不能獲取信息
        return render(request,'account/from.html',{'f':f2})
    return HttpResponse('OK')
Views
復制代碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/from1/" method="post">
    <div>
        {{ f.user }}
        {% if f.errors.user.0 %}
        <span>{{ f.errors.user.0 }}</span>
        {% endif %}
    </div>
    <div>
        {{ f.pwd }}
        {% if f.errors.pwd.0 %}
        <span>{{ f.errors.pwd.0 }}</span>
        {% endif %}
    </div>
    <div>
        {{ f.email }}
        {% if f.errors.email.0 %}
        <span>{{ f.errors.email.0 }}</span>
        {% endif %}
    </div>
    <div>
        <input type="submit" value="提交">
    </div>
</form>
</body>
</html>
form.html
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django import forms

class Form1(forms.Form):
    user = forms.CharField(
        widget=forms.TextInput(attrs={'class':'c1'}),
        error_messages={'required':'用戶名不能為空'},)

    pwd = forms.CharField(max_length=4,min_length=2)
    email = forms.EmailField(error_messages={'required':'郵箱不能為空','invalid':'郵箱格式錯誤'})
forms.py

1、<form action="/from1/" method="post">中url必須要包括在/xxx/中間,因為,無論你在路由中有沒有寫最后的/在跳轉的時候,瀏覽器都會為你自動加上,所以你必須加上,不然會報錯

2、input標簽你自己可以在html中創建,也可以利用djanjo創建,利用djanjo創建的好處是,當你在input標簽中寫入數據后,提交刷新頁面的時候,數據還存在,因為在你寫的f1 = Form1(request.POST)中已經存在你所輸入的數據

3、在render(requset,{})中傳參數的時候,既可以用local()進行傳遞,又可以用字典進行傳遞

4、后台獲取數據的時候,不能通過索引進行取值,例f['user']會報錯,應該通過 . 進行獲取值

5、request.method == 'POST' 其中的POST,必須大寫,不然會報錯

一、forms.CharField()中參數總結

required=False   --------------------可以為空,默認為Ture不能為空

max_length=10       --------------------最多10個字符

mix_length=10        --------------------最少10個字符

error_messages={'required':'用戶名不能為空','min_length':'標題最少為5個字符','max_length':'標題最多為20個字符'}----自定義錯誤信息

widget=forms.TextInput()--------------默認是input標簽

widget=forms.Textarea()----------------文本標簽

widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': '郵箱'}),------為標簽設置class屬性以及顯示

下拉框,參數choices=xxx是固定格式,參數a的形式必須寫成下面這種形式,當我們往數據庫中添加數據的時候,在不從新啟動服務的情況下,下拉框中的數據不會更新,因為類下的靜態字段只創建一次,創建對象只執行__init__方法,所以必須在創建對象執行__init__方法的時候再一次執行一下靜態字段就可以達到更新的目的

a = (

  (6,'乒乓球'),

  (1,'足球'),

  (2,'籃球'),

  (3,'手球'),

)

forms.CharField( widget=forms.Select(choices=a) )

自定制驗證規則:

自己可以自定義驗證規則,加到里面

from django.core.exceptions import ValidationError
from django import forms
import re
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手機號碼格式錯誤')
pwd = forms.CharField(validators=[mobile_validate, ],
                     
                    error_messages={'required': u'手機不能為空'},
                    widget=forms.TextInput(attrs={'class': "form-control",'placeholder': u'手機號碼'}))
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError


def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手機號碼格式錯誤')


class PublishForm(forms.Form):

    user_type_choice = (
        (0, u'普通用戶'),
        (1, u'高級用戶'),
    )

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
                                                                  attrs={'class': "form-control"}))

    title = forms.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': u'標題不能為空',
                                            'min_length': u'標題最少為5個字符',
                                            'max_length': u'標題最多為20個字符'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'標題5-20個字符'}))

    memo = forms.CharField(required=False,
                           max_length=256,
                           widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'詳細描述', 'rows': 3}))

    phone = forms.CharField(validators=[mobile_validate, ],
                            error_messages={'required': u'手機不能為空'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手機號碼'}))

    email = forms.EmailField(required=False,
                            error_messages={'required': u'郵箱不能為空','invalid': u'郵箱格式錯誤'},
                            widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
form

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM