django限制匿名用户访问及重定向的方法实例


Posted in Python onFebruary 07, 2018

前言

大家应该都遇到过,在某些页面中,我们不希望匿名用户能够访问,例如个人页面等,这种页面只允许已经登录的用户去访问,在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_required
from django.utils.decorators import method_decorator
class 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 LoginRequiredMixin
class 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,我们也可以自己实现!

# 自定义LoginRequiredMixin
class 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和注册界面的实现逻辑也是一样的。

# logout
class 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类的使用和自定义,最后实现登录的重定向以及跳转!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
详谈python中冒号与逗号的区别
Apr 18 Python
Python 字符串与数字输出方法
Jul 16 Python
Python爬虫之正则表达式基本用法实例分析
Aug 08 Python
python3的输入方式及多组输入方法
Oct 17 Python
Python 给屏幕打印信息加上颜色的实现方法
Apr 24 Python
关于不懂Chromedriver如何配置环境变量问题解决方法
Jun 12 Python
Python3+Appium实现多台移动设备操作的方法
Jul 05 Python
详解python调用cmd命令三种方法
Jul 08 Python
python如何保存文本文件
Jun 07 Python
opencv 图像轮廓的实现示例
Jul 08 Python
Python中的None与 NULL(即空字符)的区别详解
Sep 24 Python
详解pandas apply 并行处理的几种方法
Feb 24 Python
Python用 KNN 进行验证码识别的实现方法
Feb 06 #Python
Python实现的径向基(RBF)神经网络示例
Feb 06 #Python
python实现淘宝秒杀聚划算抢购自动提醒源码
Jun 23 #Python
初探TensorFLow从文件读取图片的四种方式
Feb 06 #Python
用十张图详解TensorFlow数据读取机制(附代码)
Feb 06 #Python
Python实现matplotlib显示中文的方法详解
Feb 06 #Python
Python实现自动上京东抢手机
Feb 06 #Python
You might like
叶罗丽:为什么大家对颜冰这对CP非常关心,却对金茉两人十分冷漠
2020/03/17 国漫
中英文字符串翻转函数
2008/12/09 PHP
PHP中Trait及其应用详解
2017/02/14 PHP
thinkphp实现附件上传功能
2017/05/26 PHP
jQuery对象和DOM对象相互转化
2009/04/24 Javascript
JQuery里面的几种选择器 查找满足条件的元素$(&quot;#控件ID&quot;)
2011/08/23 Javascript
javascript中var的重要性分析
2015/02/11 Javascript
jQuery制作简洁的图片轮播效果
2015/04/03 Javascript
详解JavaScript基于面向对象之创建对象(2)
2015/12/10 Javascript
JavaScript  event对象整理及详细介绍
2016/10/10 Javascript
JS实现登录页密码的显示和隐藏功能
2017/12/06 Javascript
微信小程序:数据存储、传值、取值详解
2019/05/07 Javascript
微信小程序Echarts图表组件使用方法详解
2019/06/25 Javascript
el-select 下拉框多选实现全选的实现
2019/08/02 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
vue如何在项目中调用腾讯云的滑动验证码
2020/07/15 Javascript
Vue实现穿梭框效果
2020/09/30 Javascript
详解利用Python scipy.signal.filtfilt() 实现信号滤波
2019/06/05 Python
Python3 实现减少可调用对象的参数个数
2019/12/20 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
Python绘制全球疫情变化地图的实例代码
2020/04/20 Python
Expected conditions模块使用方法汇总代码解析
2020/08/13 Python
HTML5 video 视频标签使用介绍
2014/02/03 HTML / CSS
html5简介及新增功能介绍
2020/05/18 HTML / CSS
加拿大健康、婴儿和美容产品在线购物:Well.ca
2016/11/30 全球购物
三星俄罗斯授权在线商店:Samsung俄罗斯
2019/09/28 全球购物
美国领先的宠物用品和宠物食品零售商:Petco
2020/10/28 全球购物
小米官方旗舰店:Xiaomi
2020/08/07 全球购物
成品库仓管员岗位职责
2014/04/06 职场文书
董事长秘书工作职责
2014/06/10 职场文书
2014年超市工作总结
2014/11/19 职场文书
毕业论文指导老师意见
2015/06/04 职场文书
2015元旦感言
2015/12/09 职场文书
严以律己学习心得体会
2016/01/13 职场文书
AI:如何训练机器学习的模型
2021/04/16 Python
WCG2010 星际争霸决赛 Flash vs Goojila 1 星际经典比赛回顾
2022/04/01 星际争霸