国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

django限制匿名用戶訪問及重定向的方法實例

2020-01-04 15:56:30
字體:
來源:轉載
供稿:網友

前言

大家應該都遇到過,在某些頁面中,我們不希望匿名用戶能夠訪問,例如個人頁面等,這種頁面只允許已經登錄的用戶去訪問,在django中,我們也有比較多的方式去實現。

最簡單的,我們在viewz中去判斷用戶is_authenticated,但這種方法也相對比較笨拙,最理想的的我們當然不希望這個請求能夠進入到我們view,在這之前就能夠返回一個相關的response,而django其實已經給我們封裝好了相關的函數與類。下面話不多說了,來一起看看詳細的介紹吧。

基于fbv模式的login_required裝飾器

def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME,    login_url=None): # 實際上這個方法也是調用is_authenticated去判斷 pass

使用方法也很簡單:

# fbv模式from django.contrib.auth.decorators import login_required@login_required def user_info_view(request): # 用戶個人界面 pass

那么,我們希望如果是匿名用戶在訪問這個界面后能夠重定向到login界面,我們可以設置相關參數,login_required裝飾器會默認去讀取settings.LOGIN_URL,并重定向到這個頁面,如果希望更為靈活,那么我們也可以給裝飾器傳相關參數。

# fbv模式@login_required(login_url='/login/', redirect_field_name='next')def user_info_view(request): # 用戶個人界面 pass

login_url就是匿名用戶訪問后重定向的url,一般都是login的頁面

redirect_field_name是一個get請求的參數

假設當前頁面會/user/info/

那么重定向的url為: /login/?next=/user/info/

這個參數可以用于登陸后直接跳轉回這個頁面,后面還會具體介紹!

基于cbv的LoginRequiredMixin類

博主一般常用都是cbv模式,在這個模式下,我們會重寫get和post方法,理論上可以用login_required裝飾器去裝飾這兩個方法

# cbv模式from django.contrib.auth.decorators import login_requiredfrom django.utils.decorators import method_decoratorclass UserInfoView(View): @method_decorator(login_required(login_url='/login/', redirect_field_name='next')) def get(self, request): # 獲取用戶個人界面  pass

login_required是函數裝飾器,method_decorator可以將函數裝飾器轉化成方法裝飾器。如果這里還有post請求,那這樣的代碼我們還要在寫一遍,這樣就顯得有點冗余,我們既然用了類來實現,當然通過類的優勢來實現!繼承LoginRequiredMixin!

from django.contrib.auth.mixins import LoginRequiredMixinclass UserInfoView(LoginRequiredMixin, View): def get(self, request): # 獲取用戶個人界面  pass

那么,LoginRequiredMixin是怎么去實現的呢?

看看源代碼

class LoginRequiredMixin(AccessMixin): def dispatch(self, request, *args, **kwargs):  if not request.user.is_authenticated():   return self.handle_no_permission()  return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)

其實它重寫了dispatch方法,因為我們還繼承了view,其實它重寫的view中的dispatch函數,如果知道view的邏輯,你就知道為什么能夠這樣實現了!

當我們在url中,調用你的view類,如UserInfoView.as_view()方法,它會去調用dispatch() ,這個方法起到一個分配器的作用,如果get請求,那么他就調用get方法,如果是post請求,那么就調用post方法。那么,在dispatch中去判斷用戶是否登錄,當然可以起到這個作用。

那既然只是重寫dispatch,我們也可以自己實現!

# 自定義LoginRequiredMixinclass LoginRequiredMixin(object): @method_decorator(login_required(login_url='/login/', redirect_field_name='next')) def dispatch(self, request, *args, **kwargs):  return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)

當然,有沒有必要自己實現,那就看各自的需求啦~

重定向與跳轉

(login_url='/login/', redirect_field_name='next')

這兩個參數提供了一個重定向與跳轉的url給我們,當匿名用戶登錄需要登錄的頁面時,就會跳轉到login_url,這個get請求還帶著redirect_field_name參數,值是'next'。

假如他訪問的是個人頁面,那么跳轉到

http://127.0.0.1/login/?next=/user/info/

我們可以通過這個參數,在登錄后直接跳轉到個人頁面。

class LoginView(View): """ 用戶登錄邏輯 """ def get(self, request):  # 獲取到next參數,渲染到template中,在form表單添加一個hidden類型的元素  next = request.GET.get('next', '')  return render(request, "login.html", {'next': next}) def post(self, request):  login_form = LoginForm(request.POST)  if login_form.is_valid():   user_name = request.POST.get("username", "")   pass_word = request.POST.get("password", "")   next = request.POST.get('next', '')   user = authenticate(username=user_name, password=pass_word)   if user is not None:    if user.is_active:     login(request, user)     if next:     # 如果next存在,直接跳轉到指定頁面      return HttpResponseRedirect(next)     # 不存在跳轉到index界面     return HttpResponseRedirect(reverse('index'))    else:     return render(request, "login.html", {"msg": "用戶未激活"})   else:     return render(request, "login.html", {"msg": "用戶名或密碼錯誤"})  else:   return render(request, "login.html", {"login_form": login_form})
# login.html template form中添加<input name="next" type="hidden" value="{{ next }}"/>

普通頁面的登錄跳轉問題

如果普通頁面也想要實現登錄后跳轉回原來的頁面,十分簡單,在request中有個path參數,它表示當前頁面,我們只需要在跳轉到login界面把這個參數帶上即可

# template<a class="loginbtn" href="/login/?next={{ request.path }}" rel="external nofollow" >登錄</a><a class='logoutbtn' href="/logout/?next={{ request.path }}" rel="external nofollow" 退出</a><a class='registerbtn' href="/register/?next={{ request.path }}" rel="external nofollow" 注冊</a>

login的實現邏輯同上面的一樣,其實logout和注冊界面的實現邏輯也是一樣的。

# logoutclass LogoutView(View): def get(self, request):  next = request.GET.get('next', '')  logout(request)  try:   return HttpResponseRedirect(next)  except:   return HttpResponseRedirect(reverse('index'))

后言

本篇重點在于@login_required裝飾器的使用,以及LoginReqiredMixin類的使用和自定義,最后實現登錄的重定向以及跳轉!

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到python教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 河源市| 开平市| 三门峡市| 阳山县| 新乡市| 滨州市| 会同县| 肃宁县| 翼城县| 泰来县| 杭锦旗| 平昌县| 通河县| 甘洛县| 南江县| 赣州市| 赫章县| 涪陵区| 湘阴县| 永修县| 喀喇沁旗| 天等县| 东安县| 台北县| 罗甸县| 潮州市| 阿克陶县| 连州市| 天柱县| 扎囊县| 汉川市| 永福县| 大悟县| 洪湖市| 兴化市| 抚宁县| 南澳县| 西昌市| 广西| 达拉特旗| 东明县|