python的Web框架,auth权限系统 使用django默认权限系统实现用户登录退出

判断用户是否登录
request.user.is_authenticated

返回的为bool值

一个简单的登录视图范式:

 1 # 导包
 2 from django.contrib.auth import login, logout, authenticate
 3 
 4 def loginview(request):
 5 
 6     # 判断是否登录,如果没有登录,这个user就是一个匿名用户(AnonymousUser)。
 7     if request.user.is_authticate:
 8         return redirect(reverse('teacher:index')) #如果登录了则跳到首页
 9     
10     if request.method == 'POST':
11         username = request.POST.get('username', '')
12         password = request.POST.get('password', '')
13         
14         #校验用户名和密码,验证成功会返回一个用户,失败则返回一个None
15         user = authenticate(username=username, password=password)
16         
17         if user is not None:
18             # 登录,将用户信息保存到session
19             login(request, user)  # 绑定(接受)当前的request请求,拿到request中的session,并传入user
20         
21             return redirect(reverse('teacher:index'))
22 
23     return render(request, 'teacher/login.html')
24     
25     
26     
27 # 简单退出视图
28 def logoutview(request):
29     # 用户是否登录都可以logout,不会抛出异常。
30     logout(request)
31     return redirect(reverse('teacher:index'))

html中有一个user的上下文处理器的全局变量,所有的模板可以直接使用

{{ user.username }}

限制登录访问

如果没有登录就禁止访问网页
在函数视图中简单配置即可:

    # 如果当前用户没有登录,则返回登录页面
    if not request.user.is_authenticated:
        return redirect(reverse('teacher:login'))

但是使用了这个之后,无法跳转到我当前进入的网页。下面去解决这个问题。

登录后的跳转

限制登录访问后,在登录之后,自动跳转到当前需要访问的页面。参数传递方法

 1 流程逻辑范式:
 2 
 3 # 传参数
 4 def students(request):
 5     if not request.user.is_authenticated:
 6         # 通过参数来传递当前的页面。
 7         return redirect(reverse('teacher:login') + '?next=%s' %request.path_info )
 8         
 9         
10 # 在login中接受参数并跳转,GET和POST同样需要设置,此处只示例GET
11 def loginview(request):
12     # 获取next参数
13     next_url = request.GET.get('next')
14     # 如果当前登录了账号。则跳转到初始访问的网页
15     if request.user.is_authenticated: 
16         if next_url:
17             return redirect(next_url)
18     
19         # 如果没有登录,则跳转到登录的页面
20         else:
21             return redirect(reverse('teacher:login')

如果这样写的话,那就是每一个APP都需要需要加上判断和传参数代码。比较麻烦。而django为我们提供了一个方法,那就来看看把。

login_required:装饰器跳转

# 导包
from django.contrib.auth.decorators import login_required

范式

1 login_url为当没有next的时候需要跳转的地方
2 @login_required(login_url=reverse('teacher:login'))
3 def students(request):
4     pass

如果不写login_url的话,会报错,就我们需要在settings中配置LOGIN_URL。

@login_required()
def students(request):
    pass
    
    
settings中配置:
from django.urls import reverse_lazy, reverse
LOGIN_URL = reverse_lazy('teacher:login')

reverse_lazy:懒加载,如果直接配置reverse则会报错,因为settings是最早加载的,而APP等其他的还每有加载,立即加载是找不到我们需要的网页。

django内置权限系统管理

>>> admin.has_perm('teacher.add_student')

判断admin是否有'teacher.add_student'的权限。
# has_perm 是否有这个表的字段

返回bool值

在view中的应用:

1 @login_required()
2 def students(request):
3     if not request.user.has_perm('teacher.view_students'):
4         return HttpResponse('你没有权限查看')
5     pass
6     ......
权限的装饰器方法
第一个参数:代表当前的权限位置,第二个参数代表:报错抛出的异常
@permission_required('teacher.view_students', raise_exception=True)

HTML中判断用户登录的常规写法

    <!--判断用户是否登录-->
    {% if user.is_authenticated %}
        <li><a href="#">{{ user.username }},欢迎您</a></li>
        <a href="{% url 'teacher:logout' %}">安全退出</a>
    {% else %}
      <li><a href="{% url 'teacher:login' %}">欢迎游客,请登录</a></li>
    {% endif %}

HTML中根据权限显示展现的功能

    <!--如果有添加students的权限,则显示添加这个a标签-->
    {% if perms.teacher.add_students %}
    <a href="{% url 'teacher:add' %}" class="btn btn-primary" role="button">添加</a>
    {% endif %}

删除权限

>>> 用户名.user_permissions.clear()

html权限的简单操作

{% if perms.teacher %}说明有teacher app 的权限{% endif %}

{% if perms.teacher.add_students %}说明有teacher students 模型add 的权限{% endif %}

自定义权限

写在models的模型下定义

1 class Meta:
2     permissions = (
3         
4         ('can_deleta_students', '删除学生')
5     )
6 
7 # 这样定义后,需要数据库迁移