用Django全栈开发——23. 增加访问权限以及404页面
家人们好!由皮老爷爷为大家带来最新的一期《学习Python能干啥?》之Django教程!从零开始入门到精通的内容!这一章我们专注于实现404错误页面的功能与显示效果!
皮爷的每一篇文章,都配置相对应的代码。这篇文章的代码Tag是Post_023

在之前的章节中, 我们对网站的功能进行了开发, 基本功能已经接近完成. 接下来的一章, 我们将负责管理权限设置.
权限管理分析
为什么需要权限管理?
在当时的第11讲课程中进行了一次Login功能的开发,并在此过程中创建了一个超级管理员账号;随后,在后续章节中又逐步构建起了一个完善的后台管理系统。
尽管我们提供了管理员账号以及登录功能,并非所有细心的同学都会发现我们的CMS系统实际上无需登录即可使用。
这就是Bug啊!这就是问题啊!如果在正式发布环境中出现这种情况的话,岂止是允许别人轻而易举地就可以登录后台呢?甚至还能管理你的文章。
今天早晨, 我们将为 CMS 系统设置权限. 以便所有访问该系统的用户都需要先完成认证流程. 未经认证则无法访问.
原理详解
一旦某个页面的登录状态未被设置为已登录状态,则无法进入。
能够实现此功能的元素应当只是请求相关的功能模块。
各位有没有注意到呢?每次编写视图函数时无论采用的是POST还是GET方法或者其他常用的方法都需要传递一个request参数并且是强制要求的。那么这个request具体有什么样的属性呢?它其实就是指的就是WSGIRequest类:

他是继承自django.http.HttpRequest类,这个类的官方文档:
https://docs.djangoproject.com/en/3.0/ref/request-response/
针对我们的团队,在为了使用户在登录后才能访问系统的情况下,则可以观察到,在Httprequest对象中存在一个名为user的字段。通过这个字段的值进行判断即可。
核心的代码,其实就是下面这段:
if request.user.is_authenticated:
... # Do something for logged-in users.
else:
... # Do something for anonymous users.
我们的目标是利用修饰器来完成权限管理。我们需要了解的是什么是修饰符以及其具体应用方式。它前接于该方法,并借助注解符号@xxx的形式进行标注。
登出方法
我们之前已有的Login页面上具备了登录功能,在此基础上还需要实现一个注销功能,并将其放置于CMS主导航栏中。
def logout_view(request):
logout(request)
return redirect(reverse('cms:login'))
权限实战
既然我们的目标是权限管理,那么我们需要在PeekpaUser应用中创建decorators.py文件,并在此处编写相应的装饰器代码。
def peekpa_login_required(func):
def wrapper(request, *args, **kwargs):
if request.user.is_authenticated:
return func(request, *args, **kwargs)
else:
if request.is_ajax():
return restful.unauth(message='请先登录!')
else:
return redirect(reverse('cms:login'))
return wrapper
那么我们将这个装饰器引入到CMS环境中,并部署于cms_dashboard和category_manage_view进行测试。
@peekpa_login_required
def cms_dashboard(request):
@peekpa_login_required
def category_manage_view(request):
此时,在浏览器中输入DASHBOARD的URL地址http://localhost:8000/cms/dashboard/(通过这一操作后),在网页上会出现一个跳转链接

观察到right-bottom网络内部的URLhttp://localhost:8000/cms/dashboard/返回了一个302状态码, 因此导致浏览器直接被重定向至登录页面
同样查看一下category manage的相关信息,请访问以下链接:http://localhost:8000/cms/dashboard/category/manage。

右下角显示的是一样的。302返回结果,自动跳转到了login页面。
然而此时 我们可以访问 category publish 页面 由于该页面未配置装饰器 其路径为 http://localhost:8000/cms/dashboard/category/publish

可以看出,直接进入来了,并且功能与之前的开发完全相同。这表明修饰器仍然管用。
再一次返回到category manage的页面,并进行一次登录操作之后,请问是否能再次进入该页面。

使用后体验非常良好。因此,在开发cms时如果想实施权限验证只需在视图函数前加入@peekpa_login_required即可。
在这个时候,
细心的同学可能会注意到,
我们这里所有的修饰器实际上是作用于方法的。
值得注意的是,在我们的系统中存在这样的情况:
某些视图函数实际上映射到了视图类对象。
此链接地址:http://localhost:8000/cms/dashboard/exchangelink/edit?exchangelink_id=1
对应的后端映射对象即为ExchangeLinkEditView。
在未进行任何改动的情况下访问此地址可以直接成功地跳转到ExchangeLink的修改页面

基于目前我们尚未为视图类实施任何防护措施。鉴于此,在此处有必要应用@method_decorator装饰器,并将以下步骤纳入实施流程:
@method_decorator(peekpa_login_required, name='get')
class ExchangeLinkEditView(View):
def get(self, request):
exchangelink_id = request.GET.get('exchangelink_id')
exchangeLink = ExchangeLink.objects.get(pk=exchangelink_id)
context = {
'item_data': exchangeLink,
'list_data_status': ExchangeLink.STATUS_ITEMS,
}
return render(request, 'cms/exchangelink/publish.html', context=context)
第一个参数是用于执行功能的装饰器工具;第二个参数则指定需要进行相应的处理。我们仅对GET请求进行相应的处理;若希望同时处理POST请求,则设置name=dispatch
当前时间点, 我们接下来将前往http://localhost:8000/cms/dashboard/exchangelink/edit?exchangelink_id=1页面

就会发现,页面被自动跳转到了login页面。右下角也是看到了302请求。
404页面
404页面是一个常见的网络状态码之一。当我们的服务正常运行时,在访问一个从未访问过的URL地址(如http://127.0.0.1:8000/mm)时,默认情况下会显示该状态码并提示相应信息

当你看到这个页面,说明这么几点问题:
- 在你的settings.py文件中,“DEBUG”变量被设置为True。
- 如果你未编写404页面,默认会显示为系统默认的调试错误页面。
如果必须在settings.py中进行设置以查看真实的404页面,则需要重新配置设置中的DEBUG和ALLOWED_HOSTS参数为以下内容:
DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1']
他们分别表示,当前网站不是debug模式,允许访问的host地址是127.0.0.1
那么这个时候,我们再次访问http://127.0.0.1:8000/mm,就会看到这样:

这个白色的页面,其实就是系统自带的404页面。
我们需要自定义我们的页面。只需在template目录中创建名为404.html的页面即可:

此时, 为了查看那个原本并不存在的页面而重新启动服务器后访问它时会显示出来

请告知我们当前页面的情况如何?是否实现了我们的定制需求?Django极为强大, 通过非常简便的方式成功实现了错误信息的处理.
技术总结
最后总结一下,
访问权限和404:
- 为了保障用户的访问权限需求,则应在代码中利用HttpRequest.user进行判断;
- 通常情况下,则是通过装饰器的方式来实现功能;
- 对于方法修饰器,在代码前直接添加
@xxx即可完成修饰;而对于类则使用@method_decorator(peekpa_login_required, name='get'); - 404页面则需要在templates模板中直接生成一个名为
404.html的文件即可; - 如果想要查看真实的404页面效果,则必须将settings.py中的参数设置为DEBUG=True,并同时配置好settings.py中的ALLOWED_HOSTS值;
- 感谢您的阅读与使用。
整套教程源码获取,可以关注『皮爷撸码』,回复『peekpa.com』
长按下图二维码关注,如文章对你有启发,欢迎在看与转发。

