二十一、auth系统
django自带的用户身份验证系统
1.用户验证:登录的账号是否是真正的用户
2.授权:允许用户做什么
一、用户验证
1.1、实现登录
1.view.py里面
def login_view(request):
# user = request.user
#判断是否登录
if request.user.is_authenticated: #匿名用户返回false
return redirect('test1:student_list')
if request.method == 'POST':
#获取用户名和密码
username = request.POST.get('username')
password = request.POST.get['password']
#校验码用户名和密码
user = authenticate(username=username, password=password) #正确返回user对象,错误返回none
if user is not None:
# 用户信息存放到session并登录。
login(request,user)
return redirect('test1:student_list')
return render(request,'test1/login.html')
2.index.html里面
恭喜{{ user.username|default:'游客' }}访问
{% if user.is_authenticated %}
<a href="{% url 'test1:logout' %}">退出</a>
{% else %}
<a href="{% url 'test1:login' %}">登录</a>
{% endif %}
1.2、实现退出
def logout_view(request):
logout(request)
return redirect('text1:index')
1.3、实现限制
在student_list里面添加
#限制登录
if not request.user.is_authenticated: #未登录用户访问,返回登录页面
return redirect('test1:login')
1.4、限制优化
#登录优化一:实际开发过程中间,如果我要访问某个页面,而这个页面需要登录权限,我们登录后自动转回此前我想访问的页面。
#处理方法,把当前的路径当做参数传入
保留/拼接路径:request.path.path_info
#return redirect(reverse('test1:login')+'?next={}'.format(request.path.path_info))
#登录优化二:多个视图都要这个功能,需要每个视图加上向他的内容会出现代码冗余,处理方式:装饰器
from django.contrib.auth.decorators import login_required
删除原来的限制登录代码,在def上面加上装饰器:@login_required
@login_required
def student_list(request):
#限制登录
# if not request.user.is_authenticated: #未登录用户访问,返回登录页面
# return redirect(reverse('test1:login')+'?next={}'.format(request.path.path_info))
#student/login/?next=test/test1/student_list
# settings.py
from django.urls import reverse, reverse_lazy
LOGIN_URL = reverse_lazy('test1:login')
二、授权
添加权限:从左边的框里面搜索相应的权限,然后全选,点击下卖弄的全选就可以添加到右边的方框里面。
在manage.py里面查看
from django.contrib.auth.models import User, Group , Permission
u1.groups#分组
u1.user_permission#权限
查看有无权限
user = User.objects.last()
user.has_perm(‘student.add_grade’)
对某个app.权限_某个表
1.权限验证
1.view.py
from django.contrib.auth.decorators import login_required,permission_required
@permission_required('student.view_student',raise_exception=True)
@login_required
def student_list(request):
#确认是否有权限
# if not request.user.has_perm('student.view_student'):
# return HttpResponse('你无权查看')
二十二、类视图
一般命名规则:
函数:下划线
类:大驼峰
前端:小驼峰
路径自动找函数,需要把请求和相关参数发送给函数,但是发送不了给类。
类函数的路径:path(‘my_oh/’,views.MyView.as_view(),name=‘my_oh’),
1.类视图使用表单
class Register(View):
def get(self,request):
form = RegisterForm()
return render(request, 'test1/register.html', context={
'form':form,
})
def post(self,request):
form = RegisterForm(request.POST)
if form.is_valid():#进行字段校验,校验成功返回true
password = form.cleaned_data.get('password')
password_repeat = form.cleaned_data.get('password_repeat')
if password == password_repeat:
return HttpResponse('注册成功')
return render(request, 'test1/register.html', context={'form': form,})
2.通用视图
2.1 ListView
注意:自己app下的视图必须使用自己app下的models的数据库,不然会报错。
# 案例:学生列表修改成listview
class StudentListView(ListView):
section = '学生列表'
template_name = 'test1/student_list.html'
model = Student
context_object_name = 'students' #正常为object_list 这里可以改名
paginate_by = 3#每页展示条数
#第一步优化:过滤+搜索
section = '学生列表'
#查询功能
def get_queryset(self): #过滤
search = self.request.GET.get('search','').strip()#最后的是去除两边的空格
per_page = self.request.GET.get('per_page', 10)
self.paginate_by = int(per_page)
if search:
if search.isdigit():#如果是数字查看是qq还是电话
sts = Student.objects.filter(Q(qq=search)|Q(phone=search), is_delete=False)
else:
sts=Student.objects.filter(name=search)
else:#如果没有查询内容,返回全部
sts = Student.objects.filter(is_delete=False)
students = sts.order_by('-c_time') # 排序
self.students = students
return students
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs) #注意继承父类
context['section'] = self.section
context['per_page'] = self.paginate_by
context['total_page'] = math.ceil(self.students.count()/int(context['per_page']))
context['page'] = self.request.GET.get('page',1)
return context
2.2 detailView
展示具体某个对象
#学生详情修改成datailView
class StudentDetailView(DetailView):
section = '学生详情'
template_name = 'test1/student_detail.html'
model = Student #模型
context_object_name = 'student' #改名
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs) #注意继承父类
context['section'] = self.section
return context
2.3.类装饰器
1.直接在url配置部分
# path('student_list/', views.StudentListView.as_view(),name = 'student_list'),
path('student_list/', login_required(views.StudentListView.as_view()),name = 'student_list'),
2.装饰类
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
@method_decorator(login_required())
def dispatch(self, request, *args, **kwargs):
return super().dispatch( *args, **kwargs)
3:直接
@method_decorator(login_required, name='dispatch')
class StudentListView(ListView):
······
如果想获取更多有关python的信息,和想玩python制作的小程序,可以关注微信公众号(dreamspy)。我们一起用python改变世界,一起用python创造梦想。