还记得我们之前在登陆页面 做的那个 注册账号的超链接么?
我们现在要想想,用户点击注册账号后,要实现个什么效果?
有 以下几种设计:
- 切换到另一个页面,一个注册页面,里面有用户名密码确认密码 注册按钮。
- 直接使用用户在登陆界面输入的用户名/密码,进入后台完成注册,给用户弹窗提示注册成功!
- 弹出一个弹层,上面有用户名/密码输入框和注册按钮。
4.弹出一个弹窗,上面显示“公司内部平台,注册账号需要联系xxx” 然后等别人联系你了,再由你去数据库后台去创建这个用户。
我们本章节就按照最简单的方式来,毕竟我们的重点是之后的接口测试模块,并不是用户管理模块。所以我们选择第2种 ,简单粗暴。
好,打开login.html,找到这个注册按钮,发现它是一个a标签,a标签不但在href属性中可以写一个超链接,也可以在href中写一个js函数。
这里因为我们要传递用户名/密码 作为数据,所以href属性要写一个js函数,就取名为:register()吧。具体写法:javascript:函数名()
然后在下面的已有的script标签内,在login()函数上增加一个register()函数
这个注册函数的 功能 和登陆函数,其实大同小异。都是把用户名/密码传入给后台。所以格式基本一致,你直接复制粘贴,然后改改就可以:这里我们接收到返回值后不再 直接弹出写死的文案了,而是选择弹出请求返回值,具体显示什么由后台决定。而后台的返回值就是ret。所以我们alert(ret) 。
为什么要这么做呢?因为用户注册最少有两种结果:
- 注册成功
- 用户已存在注册失败
- 其他问题,如密码过短等等违反你自己定义的规则。
所以为了后续方便我们增加规则等这样做就会很方便。
然后我们去urls.py中 写好这个注册的映射:
然后去views.py中构建好这个register_action()函数
这里可以看到,我们依然是先获取到了 前端给的用户名/密码。
然后从这个django.contrib/auth.models 库里倒入里User方法。(其实User是orm方式操作用户表的实例)
然后我们直接用User.objects.create_user方法生成一个用户,参数为用户名和密码。然后保存这个生成的用户 就是注册成功了。
但是如果用户表中已存在这个用户名,那么,这个生成语句就会报错。所以我们用try来捕获这个异常,如果发送错误那就是“用户已经存在”,如实给用户返回这句话。如果没问题,那么就返回 注册成功。
然后我们切换回浏览器,确保服务没有因为报错而中止。如果报错中止,就是因我们先写urls.py后,没有来得及写后台对应函数就切换了pycharm,导致django热重起,然后发现没有函数就报错停止了。我们现在写好了,那就直接重启就好了,如果过程中按照教程出现其他报错,请留言即可我会耐心解答。
现在我们刷新页面来测试,先登陆一个账号:
用户名 测试开发干货 密码123。
1.点击登陆,提示用户名密码错误。因为这时候还不存在这个账号
2.点击注册账号,提示注册成功
3.再点击登陆按钮!
重点来了!仍然报错哦!
为什么会发生这种事呢?
实际上 账号已经注册成功,我们的登陆函数也走到了登陆成功的分支。
我们明明写好了 要跳转到/home/ ,但是前端没有跳转,还给了个错误提示。
这里要引入一个新知识点,就是我们前端 想给后端 传数据,发送请求,如果不是表单提交,或者超链接。只用我们的异步接口请求(就是我们前面用的$.get("url",{参数}{返回动作函数})) 的话,那么后端无论怎么写重定向语句,都是徒劳的,前端并不会直接跳转去/home/。
但是我们又不想去大改前端的登陆架构,用什么办法弥补呢?
答案很简单,后端可以返回诸如 True/False 0/1 成功/失败 这种字符串。因为前端的js函数里接受到ret就是这个后端返回的字符串。所以前端js可以根据这个ret来作出不同的处理,比如跳转到/home/。这就像雨化田台词 :你东厂办不了的事,禀告我们西厂,我们西厂来办。你们管的了的我们要管,管不了的我也要管,先斩后奏,皇权特许,这!就是西厂,够不够清楚?
所以赶在这次就会,就要训练好我们的应急处理能力,将来线上出现bug,我们要以最小代价紧急修复的 次数不会少。你不那每次都完全重构吧?所以这里给大家埋了一个坑,提升一下这方面的经验。
那么现在我们修改后端login()函数,让他别操心的重定向了,直接就返回 成功 还是 失败 就行,其余的事交给前端js
然后回到前端js,改动如图:
其实就是写了一个if判断,如果ret是成功俩个字,。那么就用固定的跳转语句跳到/home/ 如果不是成功俩个字,那么再提示 报错文案。
现在我们去试登陆一下:用户名:测试开发干货 密码:123
点击登陆按钮,发现登陆成功,成功进入了home.html !
好了。到此我们的注册功能算是开发完成。
然后再补充一点:关于登陆页面的密码 输入框:
我们之前 是能显示出来具体密码的:
那是因我们input属性 就是个普通输入框,不能因我咱们给他起名密码,浏览器就智能的把它当密码输入框了。
要想显示*****,只需要给input标签 的type属性 从text改成password即可
然后我们打开浏览器 再进入到登陆页面看看:127.0.0.1:8000/login/
可以看到全都已经成功隐藏了。
最后有多疑的同学提问了,那么其他用户为啥一定要 先经过login.html 登陆成功 再进入home.html主页呢?她直接访问:ip:8000/home/ 不可以么?
答案是:目前可以直接访问,不信你不登陆试试看,一样可以。那是因我们进入home页面的函数 home() 并没有强制要求 检查登陆状态。
所以django是默认放行的。那么要如何避免这种钻空子的状况呢?
答案很简单,首先我们要给home()函数 加上django自带的登陆态检查装饰符login_required ! 导入后,直接加在home函数头上即可!
现在你再试试直接浏览器访问:127.0.0.1:8000/home/ 看看什么效果?
就会报错 让你进不去!
然后我们再 去修改login函数中成功登陆的分支,给他加上:
如果用户一但登陆成功,就调用django的真正登陆函数auth.login。然后顺便把这个登陆状态也就是成功的用户名当作session写进用户的浏览器内,之后用户就可以成功进入各个页面了。
现在我们再来试试看:
- 非登陆状态 无法直接进入/home/ , 报错
- 登陆状态进入/home/ 成功进入home.html
- 先进入/login/ ,登陆成功,发现成功跳转到home.html
上面的测试结果,还有一点需要完善。就是当用户非登陆状态,直接进入/home/时候 不应该报错,而是应该跳转到login.html页面让其先登陆。所以我们继续改动俩个地方:
- welcome函数 也加上 登陆态检查装饰符,之后我们几乎每个重要页面都要加上这个装饰符
2.urls.py中加入非登陆状态 自动跳到登陆页面的映射
好了,等待django重启,然后刷新页面我们再进行上述测试!
就会发现,当用户非登陆状态时,直接打开/home/ 或者/welcome/ 的时候,都会先跳到/login/ 页面上。登陆成功就可以继续使用,失败则永远停留在login.html中,一点空子都不让钻。
好了,今天分享到这里了。把这个链接 发送给你的同事,让他们试着创建账号 登陆吧?
http://你电脑的ip:8000/home/