auth系统与类视图
1. 使用django默认权限系统实现登录
基于cookie的会话,同时处理身份验证与授权
实例:使用默认的认证系统实现登录功能。修改view.py中登录登出代码:
from django.contrib.auth import login,logout,authenticate from crm.settings import UPLOAD_ROOT from django.db.models import Q import os # Create your views here. def index(request): #会话保持session name = request.session.get('name') return render(request,'teacher/index.html',context={'name':name})
def loginview(request): #先判断是否登录 if request.user.is_authenticated: return redirect(reverse('teacher:index')) if request.method == 'POST': username = request.POST.get('username','') password = request.POST.get('password','') #校验 用户名密码 user = authenticate(username=username,password=password) if user is not None: #登录,将用户信息保存到session login(request,user) return redirect(reverse('teacher:index')) return render(request,'teacher/login.html') def logoutview(request): logout(request) return redirect(reverse('teacher:index'))
index.html代码如下:
<p>欢迎 <span style="color: blue">{{ user.username|default:'游客' }}</span>登录</p> <p><a href="{% url 'teacher:logout' %}">安全退出</a></p>
login.html代码如下:
<h1>登录</h1> <form action="" method="post"> {% csrf_token %} <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="password" name="password"></p> <p><input type="submit" value="登录"></p> </form>
实例二:限制登录访问
复杂方法实现
from django.contrib.auth import login,logout,authenticate# Create your views here. def index(request): #会话保持session name = request.session.get('name') return render(request,'teacher/index.html',context={'name':name}) def loginview(request): #获取请求路径 next_url = request.GET.get('next') #先判断是否登录 if request.user.is_authenticated: if next_url: #判断是否带有请求路径 return redirect(next_url) else: return redirect(reverse('teacher:index')) if request.method == 'POST': username = request.POST.get('username','') password = request.POST.get('password','') #校验 用户名密码 user = authenticate(username=username,password=password) if user is not None: #登录,将用户信息保存到session login(request,user) if next_url: #判断是否带有路径 return redirect(next_url) else: return redirect(reverse('teacher:index')) return render(request,'teacher/login.html') def logoutview(request): logout(request) return redirect(reverse('teacher:index')) def students(request): if not request.user.is_authenticated: return redirect(reverse('teacher:login')+"?next=%s" %request.path_info) section = '学生列表' #获取查询参数 search = request.GET.get('search','').strip()
实现了访问students页面如果用户不登录,跳转到登录界面,登录后直接跳转到students页面。
如果有很多需要访问限制的函数,则使用装饰器login_require。替换上面的students函数即可。
from django.contrib.auth.decorators import login_required
@login_required() 会到在settings中找到LOGIN_URL def students(request): section = '学生列表' #获取查询参数 search = request.GET.get('search','').strip()
settings.py中添加
from django.urls import reverse_lazy,reverse LOGIN_URL = reverse_lazy('teacher:login')
实例三:django内置权限系统原理
1.页面操作
如何验证用户有没有某种权限has_perm(app名.操作名_模型名)
4.权限验证
@login_required() def students(request): if not request.user.has_perm('teacher.view_student'): return HttpResponse('你没有权限查看') section = '学生列表' #获取查询参数 search = request.GET.get('search','').strip()
或者使用装饰器完成
from django.contrib.auth.decorators import login_required,permission_required @login_required() @permission_required('teacher.view_student',raise_exception=True) def students(request): section = '学生列表' #获取查询参数 search = request.GET.get('search','').strip()
在模板中使用权限:
index.html代码中使用登录用户显示用户名
{% if user.is_authenticated %} <p>欢迎,{{ user.username }}</p>登录 <p><a href="{% url 'teacher:logout' %}">安全退出</a></p> {% else %} <p>欢迎游客访问 <a href="{% url 'teacher:login' %}">请登录</a></p> {% endif %}
实例:在没有‘增加’权限用户登录时,不显示“添加”按钮
{% if perms.teacher.add_student %} <a class="btn btn-primary" role="button" href="{% url 'teacher:student_add' %}">添加</a> {% endif %}
权限验证的补充,index.html
{% if user.is_authenticated %} <p>欢迎,{{ user.username }}</p>登录 <p><a href="{% url 'teacher:logout' %}">安全退出</a></p> {% else %} <p>欢迎游客访问 <a href="{% url 'teacher:login' %}">请登录</a></p> {% endif %} {% if perms.teacher %}说明有teacher app的权限{% endif %} {% if perms.teacher.add_student %}说明有teacher student模型的add的权限{% endif %}
5.自定义权限
1.在数据库里直接写入
2.在模型的meta属性中自定义
修改module.py,加入Meta
class Student(models.Model): name = models.CharField('姓名',max_length=20) age = models.SmallIntegerField('年龄',default=0) sex = models.SmallIntegerField('性别',default=1) qq = models.CharField(max_length=20,unique=True,null=True,error_messages={'unique':'QQ号码重复'}) phone = models.CharField(max_length=20,unique=True,null=True) #删除年级的时候不必把学生都删除,必须可以设置年级字段为null,on_delete=models.SET_NULL,null=True grade = models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True) c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True) e_time = models.DateTimeField(verbose_name='编辑时间',auto_now=True) is_deleted = models.BooleanField(default=False) def __str__(self): return '%s-%s-%s' %(self.id,self.name,self.age) class Meta: permissions = ( ('can_delete_student','删除学生'), )
在视图中加入权限认证
@permission_required('teacher.can_delete_student',raise_exception=True) def del_student(request): pk = request.GET.get('pk',None) if pk: student = Student.objects.get(pk=pk) student.is_deleted =True student.save() return redirect(reverse('teacher:students'))
结果展示:没有删除权限的不能进行删除操作