函式和類相關知識點
阿新 • • 發佈:2021-06-15
重寫類中的某個方法
from django.utils.decorators import method_decorator class HomeView(View): #這裡重寫了父類中的dispatch方法,原來的方法中需要引數,重寫後的方法也應該需要傳入引數,原來的方法有返回值, #重寫後,這個方法也應該有返回值.這裡沒有進行其他操作,只是呼叫了父類中的dispatch方法, def dispatch(self, request, *args, **kwargs): return super(HomeView, self).dispatch(request, *args, **kwargs) def get(self, request): return render(request, "home.html") @method_decorator(check_login) def post(self, request): print("Home View POST method...") return redirect("/index/")
裝飾器
給函式加裝飾器
from functools import wraps #func為被裝飾的函式,內層函式對外層函式中的非全域性變數進行引用和使用,這個變數為自由變數,他在記憶體中不會消失。 #並且外層函式返回內層函式名,這樣的結構叫做裝飾器。 def check_login(func): @wraps(func) def inner(request, *args, **kwargs): next_url = request.get_full_path() if request.session.get("user"): return func(request, *args, **kwargs) else: return redirect("/login/?next={}".format(next_url)) return inner def login(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") if user == "alex" and pwd == "alex1234": # 設定session request.session["user"] = user # 獲取跳到登陸頁面之前的URL next_url = request.GET.get("next") # 如果有,就跳轉回登陸之前的URL if next_url: return redirect(next_url) # 否則預設跳轉到index頁面 else: return redirect("/index/") return render(request, "login.html") @check_login#寫下函式的上方,等價於這種形式logout=check_login(logout),=inner,將返回的內層函式賦值給logout,函式名具有地址屬性,下次你在呼叫這個logout函式實際上是呼叫了內層函式, def logout(request): # 刪除所有當前請求相關的session request.session.delete() return redirect("/login/") @check_login def index(request): current_user = request.session.get("user", None) return render(request, "index.html", {"user": current_user})
注意:子函式形式
def check_login(func):
def inner(*args, **kwargs):
print(666)
inner()
#這樣的結構,在函式內部再定義一個函式,這個函式是子函式,這個inner函式就是個普通的函式,但是inner函式只能夠在這個函式內部被呼叫,二不能被外部呼叫。
在CBV檢視中,給類中的方法新增裝飾器
方式一:給類中的檢視函式新增裝飾器
from django.utils.decorators import method_decorator class HomeView(View): def dispatch(self, request, *args, **kwargs): return super(HomeView, self).dispatch(request, *args, **kwargs) def get(self, request): return render(request, "home.html") @method_decorator(check_login)#多了個這種形式,但是仍然可以理解為給函式新增裝飾器post=check_login(post),仍然可以看成這種形式。在執行這個檢視函式之前進行登陸驗證下 def post(self, request): print("Home View POST method...") return redirect("/index/")
方式二:加在dispatch方法上
rom django.utils.decorators import method_decorator
#dispatch方法會根據不同的請求方法,然後呼叫類中相應的方法,如果是POST請求,則會呼叫post方法。然後把request和分組匹配結果作為引數傳過去。
#給dispatch方法新增裝飾器,是先進行登陸驗證,再呼叫相應的方法
#給類中的檢視函式新增裝飾器,是直接呼叫了這個‘函式’,在函式中進行登陸驗證,然後執行相應的操作
class HomeView(View):
@method_decorator(check_login)
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
方式三:直接加在檢視類上,但method_decorator必須傳 name 關鍵字引數,說明我要給這個類中的哪個方法新增裝飾器。如果get方法和post方法都需要登入校驗的話就寫兩個裝飾器。
from django.utils.decorators import method_decorator
@method_decorator(check_login, name="get")#給類中的get方法新增裝飾器
@method_decorator(check_login, name="post")#給類中的post方法新增裝飾器
class HomeView(View):
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
補充:
在html中寫上{%csrf_token%}就能過csrftoken認證系統,還有一種方法也可以過csrf_token認證,那就是給檢視函式加上裝飾器。
CSRF Token相關裝飾器在CBV只能加到dispatch方法上,或者加在檢視類上然後name引數指定為dispatch方法。
備註:
srf_protect,即便settings中沒有設定全域性中介軟體,即登出了settings裡面的csrfmiddlewaretoken認證。也為當前函式強制設定csrftoken認證。---->不允許跨站請求,強制保護
csrf_exempt,取消當前函式防跨站請求偽造功能,即便settings中設定了全域性中介軟體------>允許跨站請求,強制取消保護
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
class HomeView(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
或者
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class HomeView(View):
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
在檢視函式中
@csrf_exempt#允許跨站請求,就不需要csrftoken認證啦
def func2(request):
if request.method=='GET':
return render(request, 'xx.html')
else:
username=request.POST.get('username')
print(username)
return HttpResponse('ok')
@csrf_protect#強制保護
def func2(request):
if request.method=='GET':
return render(request, 'xx.html')
else:
username=request.POST.get('username')
print(username)
return HttpResponse('ok')