持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
Django 视图
以需求来驱动学习是笔者推荐的学习方式,所以,Django学习这一部分,我们一开始就已经定好了目标, 就是要通过Django开发一个发布会签到系统。所以,这一章,我们将要把这个登录功能开发出来。不要小看 这个登录噢,它包含了不少需要我们学习知识点。
来写个登录
我们将在上一章的基础上继续开发,不过这一次,我们先从前端页面写起。打开../blog/templates/index.html 文件,修改如下代码。
启动Django 服务,访问:http://127.0.0.1:8000/index/
虽然在页面上已经看到了一个登录功能,但它目前还并不可用。真正实现登录我还需要考虑以一些问题。当点击“登录”按钮时,表单(form)要以什么方式(GET/POST)提交?视图层如何验证提交的用户名密码?如果验证成功应该跳到什么页面?如果失败如何提示用户?
GET与POST请求
当客户机通过HTTP协议向服务器提交请求时,最常被用到的方法是GET 和POST。
GET—从指定的资源请求数据。
POST—向指定的资源提交要被处理的数据GET请求
先来看看GET方法是如何传参数,给form 添加属性 method="get"。
然后保存在index.html文件,重新刷新页面。输入用户名、密码,点击登录。查看浏览器URL地址栏:
http://127.0.0.1:8000/index/?username=admin&password=admin123
GET方法会将用户提交的数据添加到URL地址中,路径后面跟问题“?”,username和password 为页 面中<input>标签的name属性值,username=admin 表示用户名输入框所接收到的信息为admin。密码框password=admin123 同理。不同参数之间用“&”符号隔开。
POST请求
同样是上面的代码,再将form表单的中的属性改为methothod="post"。再次刷新页面,输入用户名密码,点击“登录”。
CSRF verification failed “CSRF verification failed.Request aborted.”
这个提示非常有意思,而且被许多初学Django的同学问到。如果你仔细阅读上面的帮助信息,那么将会知道这个错误的原因,并且找到解决办法。然而,新手往往面对错误提示时显得恐慌和手足无措,从而护略了页面上的说明。
如果你从未听说过“跨站请求伪造”(Cross-Site Request Forgery,CSRF)漏洞,现在就去查资料吧。 Django 针对CSRF的保护措施是在生成的每个表单中放置一个自动生成的令牌,通过这个令牌判断 POST请求是否来自同一个网站。
之前的模板都是纯粹的HTML,在这里要首次体验 Django板的魔力,使用“模板标签”(template tag)添加CSRF 令牌。在from表单中添加{% csrf_token %}。
然后,刷新页面并重新提交登录表单,错误提示页面消失了。
借助Firebug 前端调试工具进行查看查看POST请求。
处理登录请求
现在知道了如何通过GET/POST将表单中的数据提交给服务器,那么如何将登录数据提交给服务器呢?可以通过 form表单的action属性来指定提交的目录。
打开../urls.py文件添加一条配置。
打开sign/views.py文件,创建login_action 视图函数。
客户端发送的请求信息全部包含在request中。
首先,通过request.method方法得到客户发送的请求方式,判断其是否为POST类型。接着,通过request.POST来获取POST请求。通过.ge
方法来寻找name为“username”和“password” 的POST参数,而且如果参数没有提交,返回一个空的字符串。此处的“username”和“password”对应form表单中<input>标签的name属性,可见这个属性的重要性。
再接下来,判断POST请求得到的 username和 password 是否为“admin/admin123”,如果是则通过 HttpResponse 类返回“login success!”字符串。否则,将通过 render 返回 index.html登录将,并且顺带返回错 误提示的字典“ {'error': 'username or password error!!}”。
但是,显然index.html页面上并没有显示error的地方,所以,需要在页面中添加。
此处又使用到了Django的模板语言,添加{{error}},它对应 render反回字典中的key。好吧!现在来体验一下登录功能,分别看看登录失败和成功的效果。如图
登录成功页
显然,登录成功返回的“login success!”字符串只是一种临时方案,只是为了方便验证登录的处理逻辑,现在没有问题之后,需要通过HTML页面来替换。
我们要开发的是发布会签到系统,那么我希望登录之后默认显示发布会列表。所以,首先创建.../templates/event_manage.html页面。
修改.../sign/vies.py中的login_action函数。
此处又用到的一个新的类HttpResponseRedirect,它可以将对路径进行重定向,从而将登录成功之后的请求指向/event_manage/目录。
创建 event_manage 函数,用于返回发布会管理event_manage.html面页。
最后,不要忘记在./guest/urls.py文件中添加路径指向。urls.py
再来登录一次,试试功能吧!