AJAX異步、sweetalert、Cookie和Session初識

1、AJAX的異步示例
1. urls.py
from django.conf.urls import url
from apptest import views


urlpatterns = [
    url(r'^atest/', views.atest),
    url(r'^ajax1/', views.ajax1),
    url(r'^ajax2/', views.ajax2),
]
View Code


2. atext.HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-type" charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>

<body>
<div>
    <input type="text" id="i1">
    <button id="b1">按鈕1</button>
</div>

<div>
    <input type="text" id="i2">
    <button id="b2">按鈕2</button>
</div>


<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
    // 點擊按鈕1給ajax1發送get請求
    $("#b1").click(function () {
        $.ajax({
            url: '/ajax1/',
            type: 'get',
            success: function (res) {
                $("#i1").val(res)
            }
        })
    });

    // 點擊按鈕2給ajax2發送get請求
        $("#b2").click(function () {
        $.ajax({
            url: '/ajax2/',
            type: 'get',
            success: function (res) {
                $("#i2").val(res)
            }
        })
    });


</script>

</body>
</html>
View Code


3.views.py
def atest(request):
    return render(request, 'atest.html')


def ajax1(request):
    import time
    time.sleep(3) # 模仿網絡堵塞的時候
    return HttpResponse('ajax1')


def ajax2(request):
    return HttpResponse('ajax2')
View Code
 
 

 

4.結果解析 在頁面中首先點擊按鈕1,而後馬上點擊按鈕2,因爲按鈕1的網絡堵塞(我用time模塊模擬的堵塞),服務端會延遲幾秒才返回響應, 若是AJAX的請求是同步的,那麼按鈕2的請求必需要等到按鈕1響應後纔會被處理,而從咱們這個簡單的實例中能夠看出, 按鈕1沒有獲得響應的時候,按鈕2已經獲得響應結果了,所以能夠看出AJAX的請求是異步的。



2、Sweetalert示例 一、Bootstrap-sweetalert
    項目下載
    https://github.com/lipis/bootstrap-sweetalert

    使用方法
    https://lipis.github.io/bootstrap-sweetalert/

使用步驟
    1. 下載插件
    2. 解壓 --> 拿到dist目錄下的內容
    3. 拷貝到Django項目的static文件夾下
    4. 在HTML頁面上導入sweetalert.css和sweetalert.js

二、示例(此處只是實現了刪除的Sweetalert)
1.index頁面代碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.css' %}">
    <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}">
    <link rel="stylesheet" href="{% static 'font-awesome-4.7.0/css/font-awesome.css' %}">
    <style>
        div.sweet-alert.showSweetAlert h2 {
            margin-top: 30px;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3" style="margin-top: 70px">
            <a href="/logout/">註銷</a>
            <table class="table table-bordered table-striped">
                <thead>
                <tr>
                    <th>序號</th>
                    <th>出版社名稱</th>
                    <th>出版社地址</th>
                    <th>操做</th>
                </tr>
                </thead>
                <tbody>
                {% for publisher in publisher_list %}
                    <tr pid="{{ publisher.id }}">
                        <td>{{ forloop.counter }}</td>
                        <td>{{ publisher.pname }}</td>
                        <td>{{ publisher.addr }}</td>
                        <td>
                            <button class="btn btn-warning">
                                <i class="fa fa-pencil"></i>
                                編輯
                            </button>
                            <button class="btn btn-danger delete-btn">
                                <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
                                刪除
                            </button>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>

{% csrf_token %}

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
<script src="{% static 'sweetalert/sweetalert.js' %}"></script>
<script>
    $('.delete-btn').click(function () {
        var deleteId = $(this).parent().parent().attr('pid');
        console.log(deleteId,typeof deleteId);
        swal({
                title: "肯定要刪除嗎?",
                text: "刪除後沒法找回",
                type: "warning",  // success/info/warning/error
                showCancelButton: true,
                confirmButtonClass: "btn-danger",
                confirmButtonText: "刪除",
                cancelButtonText: "取消",
                showLoaderOnConfirm: true,  // 點擊確認按鈕以後會有一個加載的動畫
                closeOnConfirm: false
            },
            function () {  // 當點擊確認按鈕的時候會執行這個匿名函數
                $.ajax({
                    url: '/delete_publisher/',
                    type: 'post',
                    data: {id: deleteId, csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()},
                    success: function (res) {
                        if (res.code === 0){
                            // 刪除成功
                            // 在頁面上刪除當前行數據
                            var $currentTr = $('[pid=' + deleteId + ']');
                            // 更新序號
                            // 1. 先找到當前行後面全部的tr
                            var nextAllTr = $currentTr.nextAll('tr');
                            // 2. 每個tr的第一個td 依次 -1
                            nextAllTr.each(function () {
                                var num = $(this).children().eq(0).text()-1; // 這時候的this是進入循環的那個tr
                                $(this).children().eq(0).text(num);
                            });
                            // 刪掉當前行
                            $currentTr.remove();
                            // 彈框提示
                            swal('刪除成功', '準備跑路吧!', 'success');

                        }else {
                            // 刪除失敗
                            swal('刪除失敗', res.err_msg, 'error');
                        }
                    }
                })
            });
    })
</script>
</body>
</html>
View Code


2.views.py
# 首頁
def index(request):
    publisher_list = Publisher.objects.all()
    return render(request, 'index.html', {'publisher_list': publisher_list})


# 刪除出版社
def delete_publisher(request):
    delete_id = request.POST.get('id')
    res = {'code': 0}
    try:
        Publisher.objects.filter(id=delete_id).delete()
    except Exception as e:
        res['code'] = 1
        res['err_msg'] = str(e)
    return JsonResponse(res)
View Code
 
 
 3、Cookie 1、介紹
1.Cookie的由來
你們都知道HTTP協議是無狀態的。

無狀態的意思是每次請求都是獨立的,它的執行狀況和結果與前面的請求和以後的請求都無直接關係,它不會受前面的請求響應狀況直接影響,也不會直接影響後面的請求響應狀況。

一句有意思的話來描述就是人生只如初見,對服務器來講,每次的請求都是全新的。

狀態能夠理解爲客戶端和服務器在某次會話中產生的數據,那無狀態的就覺得這些數據不會被保留。會話中產生的數據又是咱們須要保存的,也就是說要「保持狀態」。所以Cookie就是在這樣一個場景下誕生。


2.什麼是Cookie
  Cookie具體指的是一段小信息,它是服務器發送出來存儲在瀏覽器上的一組組鍵值對,下次訪問服務器時瀏覽器會自動攜帶這些鍵值對,以便服務器提取有用信息。
  簡單點說,Cookie就是服務端給瀏覽器的小紙條!保存在瀏覽器端的鍵值對。


3.Cookie的原理
  cookie的工做原理是:由服務器產生內容,瀏覽器收到請求後保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上Cookie,這樣服務器就能經過Cookie的內容來判斷這個是「誰」了。


二、Django中操做Cookie(cookie是基於響應對象進行操做的) 1.設置Cookie
rep = HttpResponse(...)
rep = render(request, ...)

rep.set_cookie(key,value, max_age=秒)
rep.set_signed_cookie(key, value, max_age=秒, salt='加密鹽',...)

參數:
    key, 鍵
    value='', 值
    max_age=None, 超時時間(經常使用瀏覽器使用這個)
    expires=None, 超時時間(這個參數是針對IE瀏覽器的)
    path='/', Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie能夠被任何url的頁面訪問
    domain=None, Cookie生效的域名
    secure=False, https傳輸
    httponly=False 只能http協議傳輸,沒法被JavaScript獲取(不是絕對,底層抓包能夠獲取到也能夠被覆蓋)


2.獲取Cookie
set_cookie取值:
    request.COOKIES  --> 是一個大字典
    request.COOKIES['key'] 或者 request.COOKIES.get('key', '設置取不到值時默認使用的值')

set_signed_cookie取值:
    request.get_signed_cookie(key='', salt='set_signed_cookie的salt的值', default=獲取不到值的時候默認使用的值, max_age=None)

參數:
    default: 默認值
    salt: 加密鹽
    max_age: 後臺控制過時時間



3.刪除Cookie
def logout(request):
    rep = redirect("/login/")
    rep.delete_cookie("user")  # 刪除用戶瀏覽器上以前設置的usercookie值
    return rep



三、Cookie登陸驗證示例
1.index頁面代碼就是上面的代碼

2.login頁面代碼
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-type" charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Login</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
</head>

<body>
<div class="container">
    <div class="row">
        <div class="col-md-4 col-md-offset-4" style="margin-top: 70px">
            <h2 class="text-center">歡迎登陸</h2>
            <form action="" method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="exampleInputUser">用戶名</label>
                    <input type="text" class="form-control" id="exampleInputUser" placeholder="username" name="username">
                </div>
                <div class="form-group">
                    <label for="exampleInputPassword1">密碼</label>
                    <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password" name="password">
                </div>
                <div class="checkbox">
                    <label>
                        <input type="checkbox" name="remember" value="seven"> 七天記住密碼
                    </label>
                </div>
                <button type="submit" class="btn btn-success btn-block">登陸</button>
                <p style="color: red;">{{ error_msg }}</p>
            </form>
        </div>
    </div>
</div>


<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
</body>
</html>
View Code

3.views.py
from django.shortcuts import render, HttpResponse, redirect
from functools import wraps
from django import views
from app01.models import *
from django.http import JsonResponse
# Create your views here.


# 用裝飾器作cookie登陸驗證
def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        # 先作cookie驗證,若是cookie中有我登陸的信息,則能夠訪問指定的頁面
        if request.COOKIES.get('xm') == 'sb':
            rep = func(request, *args, **kwargs)
            return rep
        else:
            # 不然,讓用戶去登陸
            # 拿到當前訪問的url
            return_url = request.path_info
            return redirect('/login/?returnUrl={}'.format(return_url))
    return inner



# 登陸
class LoginView(views.View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        username = request.POST.get('username')
        pwd = request.POST.get('password')
        is_rem = request.POST.get('remember', None)
        is_ok = UserInfo.objects.filter(name=username, password=pwd)
        if is_ok:
            # 判斷是否從其餘頁面跳轉到登陸頁面,拿到return_url
            # 若是取不到returnUrl,默認跳轉到index頁面
            return_url = request.GET.get('returnUrl', '/index/')
            rep = redirect(return_url)  # rep就是響應對象
            # 判斷是否記住密碼
            if is_rem:
                # 是就保存七天
                rep.set_cookie('xm', 'sb', max_age=60*60*24*7)
            else:
                # 不是就不保存
                rep.set_cookie('xm', 'sb')  # 告訴瀏覽器在本身本地保存一個鍵值對
            return rep
        else:
            return render(request, 'login.html', {'error_msg': '用戶名或者密碼錯誤'})


# 首頁
@check_login
def index(request):
    publisher_list = Publisher.objects.all()
    return render(request, 'index.html', {'publisher_list': publisher_list})


# 刪除出版社
def delete_publisher(request):
    delete_id = request.POST.get('id')
    res = {'code': 0}
    try:
        Publisher.objects.filter(id=delete_id).delete()
    except Exception as e:
        res['code'] = 1
        res['err_msg'] = str(e)
    return JsonResponse(res)


@check_login
def home(request):
    return HttpResponse('home')


# 註銷
def logout(request):
    rep = redirect('/login/')
    rep.delete_cookie('xm')
    return rep
View Code
 
 
 4、Session 1、介紹
cookied的缺點:
    Cookie保存在瀏覽器端,不安全
    Cookie的長度不能超過4096字節

Session:
    Session是用於保持狀態的基於 Web服務器的方法。Session 容許經過將對象存儲在 Web服務器的內存中在整個用戶會話過程當中保持任何對象。
    通俗來講,Session就是保存在服務器端的鍵值對,Session的鍵做爲Cookie的值存在瀏覽器中,那麼即便被截取了,也只是取到了Session的鍵,
    瀏覽器發送請求時,服務端就能夠根據cookie的傳過來的值,找到Session的鍵,從而去服務器的數據庫(文件等)找到對應的值。

注意:
    Cookie和Session實際上是共通性的東西,不限於語言和框架。



2、Session的原理
    用戶名密碼經過驗證後:
    1.生成一個隨機字符串(不一樣用戶的隨機字符串是不一樣的)
    2.在後端定義一個大字典,字典的key就是上面的隨機字符串,值是你設置的值
    3.在服務器端的數據庫(或者文件等)存儲上面定義的字典(值存儲的時候,session會自動幫咱們加密)
    4.把隨機字符串當成cookie的值給瀏覽器返回(瀏覽器收到的cookie默認鍵值對是: {"sessionid": 隨機字符串})
    5.若是使用python的ORM,這個大字典會默認保存在django_session這張表中
 1、session設置值的過程
 request.session['name'] = 'xiaoming'
# 隨機生成一個字符串做爲key,key對應的值又是一個字典,字典裏面的內容纔是你request.session設置的具體值

# session數據
d = {
    'qwerioiuytr45421224ew': {'name': 'xiaoming'}
}

# 過程
import json
# 1. 字典序列化成字符串 s1 = json.dumps({'name': 'xiaoming'})
# 2. 加密算法加密一下,獲得 10e1dasdasdadasfsgdvf2rji0d2dqdsa
# 3. 存到數據庫

# 數據庫
# session_key                            session_data                                        expire_date
# qwerioiuytr45421224ew     10e1dasdasdadasfsgdvf2rji0d2dqdsa                    

# 而後把這個隨機字符串qwerioiuytr45421224ew做爲cookie的值發送給瀏覽器



2、session取值的過程
# request.session.get('name')

# 1. 先從請求攜帶的Cookie數據中拿到隨機字符串 :qwerioiuytr45421224ew
# 2. 利用session_key去數據庫查詢,拿到session_data: 10e1dasdasdadasfsgdvf2rji0d2dqdsa
# 3. 解密
# 4. 反序列化 --> 獲得一個保存當前此次請求的session數據的字典
# 5. 字典.get('name')
Session原理解析


 

 
 
3、Django中Session相關方法
經常使用: # 獲取Session中數據
request.session['k1']
request.session.get('k1',None)

# 設置Session的數據
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在則不設置

# 刪除指定的Session數據
del request.session['k1']

# 會話session的key
request.session.session_key

# 將全部Session失效日期小於當前日期的數據刪除
request.session.clear_expired()

# 刪除當前會話的全部Session數據
request.session.delete()
  
# 刪除當前的會話數據並刪除會話的Cookie。
request.session.flush() 
    這用於確保前面的會話數據不能夠再次被用戶的瀏覽器訪問
    例如,django.contrib.auth.logout() 函數中就會調用它。

# 設置會話Session和Cookie的超時時間
request.session.set_expiry(value)   
    * 若是value是個整數,session會在指定的秒數後失效。
    * 若是value是個datatime或timedelta,session就會在這個時間後失效。
    * 若是value是0,用戶關閉瀏覽器session就會失效。
    * 若是value是None,session會依賴全局session失效策略。

注意:
    失效不等於刪除,失效是那個session和cookie不能使用了,可是數據庫仍存着session的值,
    而刪除則是從數據庫中把session的值刪除了


不經常使用: # 獲取全部的鍵、值、鍵值對
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()

# 檢查會話session的key在數據庫中是否存在
request.session.exists("session_key")



四、Session版的登陸驗證
from django.shortcuts import render, HttpResponse, redirect
from functools import wraps
from django import views
from app01.models import *
from django.http import JsonResponse
# Create your views here.


# 用裝飾器作session登陸驗證
def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        # session版
        # 驗證
        session_user = request.session.get('user', None)
        if session_user:
            rep = func(request, *args, **kwargs)
            return rep
        else:
            # 不然,讓用戶去登陸
            # 拿到當前訪問的url
            return_url = request.path_info
            return redirect('/login/?returnUrl={}'.format(return_url))
    return inner


# 登陸
class LoginView(views.View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        # session版
        username = request.POST.get('username')
        pwd = request.POST.get('password')
        is_rem = request.POST.get('remember', None)
        # 不推薦使用get,由於get取不到值會報錯
        user_obj = UserInfo.objects.filter(name=username, password=pwd).first()
        if user_obj:
            return_url = request.GET.get('returnUrl', '/index/')
            request.session['user'] = user_obj.name
            # 判斷是否記住密碼
            if is_rem:
                # 是就保存七天
                request.session.set_expiry(60*60*24*7)
            else:
                # 不是的話關閉瀏覽器就失效
                request.session.set_expiry(0)
            return redirect(return_url)
        else:
            return render(request, 'login.html', {'error_msg': '用戶名或者密碼錯誤'})


# 首頁
@check_login
def index(request):
    publisher_list = Publisher.objects.all()
    return render(request, 'index.html', {'publisher_list': publisher_list})


# 註銷
def logout(request):
    # request.session.delete()  # 刪除session
    request.session.flush()  # 刪除session並讓cookie失效
    return redirect('/login/')
View Code


5、Django中的Session配置
在setting.py裏面設置的關於session的全局變量配置 1. 數據庫Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默認把session存在數據庫)

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

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎(把session存在文件中)
SESSION_FILE_PATH = None                                    # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() 

4. 緩存+數據庫
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎(把session存在數據庫和緩存中)

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎(把session存在瀏覽器中,至關於加鹽的cookie)
 其餘公用設置項:
SESSION_COOKIE_NAME = "sessionid"          # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認)
SESSION_COOKIE_AGE = 1209600                # Session的cookie失效日期(2周)(默認)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False     # 是否關閉瀏覽器使得Session過時(默認)
SESSION_SAVE_EVERY_REQUEST = False          # 每次請求都刷新Session的有效期,默認修改以後才保存(默認)

注意:
SESSION_COOKIE_AGE設置的是全局的session失效日期,
request.session.set_expiry(value)設置的是某個具體的請求的session失效日期(局部) 

不經常使用:
SESSION_COOKIE_PATH = "/"                  # Session的cookie保存的路徑(默認)
SESSION_COOKIE_DOMAIN = None                # Session的cookie保存的域名(默認)
SESSION_COOKIE_SECURE = False               # 是否Https傳輸cookie(默認)
SESSION_COOKIE_HTTPONLY = True              # 是否Session的cookie只支持http傳輸(默認)



5、使用裝飾器
1、FBV中加裝飾器
首先定義一個裝飾器
而後直接在要被裝飾的函數上一行添加裝飾器

例如:
# 裝飾器函數
def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        # 先作cookie驗證,若是cookie中有我登陸的信息,則能夠訪問指定的頁面
        if request.COOKIES.get('xm') == 'sb':
            rep = func(request, *args, **kwargs)
            return rep
        else:
            # 不然,讓用戶去登陸
            # 拿到當前訪問的url
            return_url = request.path_info
            return redirect('/login/?returnUrl={}'.format(return_url))
    return inner

# 使用裝飾
@check_login
def home(request):
    return HttpResponse('home')


2、CBV中加裝飾器相關
# CBV示例
class UserinfoView(views.View):
    def get(self, request):
        return HttpResponse('OK')

    def post(self, request):
        return redirect('/index/')

先觀察CBV的函數和裝飾器函數,明顯能夠看到,裝飾器函數的參數和CBV的函數的參數不一致, CBV的參數中多了一個self,那麼傳到裝飾器中使用的時候,裝飾器中inner的參數request就表明CBV中函數的self, 後續CBV的request就會被裝飾器的*args接收,此時是沒有問題的,可是,在裝飾器使用request的時候就出問題了, 由於裝飾器中inner的參數request就表明CBV中函數的self,而self明顯就沒有request的那些方法,因此就會報錯。

Django提供瞭解決這一問題的方法:
1.方法一
# 直接加在CBV視圖的get或post方法上
from django.utils.decorators import method_decorator

class UserinfoView(views.View):
    @method_decorator(check_login)
    def get(self, request):
        return HttpResponse('OK')

    def post(self, request):
        return redirect('/index/')

2.方法二
# 加在dispatch方法上
from django.utils.decorators import method_decorator

class UserinfoView(views.View):

    @method_decorator(check_login)
    def dispatch(self, request, *args, **kwargs):
        return super(UserinfoView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('OK')

    def post(self, request):
        return redirect('/index/')

由於CBV中首先執行的就是dispatch方法,因此這麼寫至關於給get和post方法都加上了登陸校驗


3.方法三
直接加在視圖類上,但method_decorator必須傳 name 關鍵字參數

# 若是get方法和post方法都須要登陸校驗的話就寫兩個裝飾器。
from django.utils.decorators import method_decorator

@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class UserinfoView(views.View):

    def dispatch(self, request, *args, **kwargs):
        return super(UserinfoView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('OK')

    def post(self, request):
        return redirect('/index/')


6、補充
1、CSRF Token相關裝飾器在CBV只能加到dispatch方法上,或者加在視圖類上而後name參數指定爲dispatch方法。
若是是FBV則直接添加 @csrf_exempt 便可

注意:
    csrf_protect,爲當前函數強制設置防跨站請求僞造功能,即使settings中沒有設置全局中間件。
    csrf_exempt,取消當前函數防跨站請求僞造功能,即使settings中設置了全局中間件。

2、示例
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator


class UserinfoView(views.View):

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(UserinfoView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('OK')

    def post(self, request):
        return redirect('/index/')

或者

@method_decorator(csrf_exempt, name='dispatch')
class UserinfoView(views.View):

    def dispatch(self, request, *args, **kwargs):
        return super(UserinfoView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('OK')

    def post(self, request):
        return redirect('/index/')
相關文章
相關標籤/搜索