6-4 用form实现登录-1

上面我们的用户登录的方法是基于函数来做的。本节我们做一个基于类方法的版本。
要求对类的继承有了解。

基础教程中基本上都是基于函数来做的,其实更推荐基于类来做。基于类可以带来不少好处

# 基于类实现需要继承的view
from django.views.generic.base import View
class LoginView(View): # 直接调用get方法免去判断 def get(self, request): # render就是渲染html返回用户 # render三变量: request 模板名称 一个字典写明传给前端的值 return render(request, "login.html", {}) def post(self, request): # 取不到时为空,username,password为前端页面name值 user_name = request.POST.get("username", "") pass_word = request.POST.get("password", "") # 成功返回user对象,失败返回null user = authenticate(username=user_name, password=pass_word) # 如果不是null说明验证成功 if user is not None: # login_in 两参数:request, user # 实际是对request写了一部分东西进去,然后在render的时候: # request是要render回去的。这些信息也就随着返回浏览器。完成登录 login(request, user) # 跳转到首页 user request会被带回到首页 return render(request, "index.html") # 没有成功说明里面的值是None,并再次跳转回主页面 else: return render(request, "login.html", {"msg": "用户名或密码错误! "}) 
mark

继承的view中的方法。

django1.9.8 urls中的配置:

# 换用类实现
from users.views import LoginView# 基于类方法实现登录,这里是调用它的方法 url('^login/$', LoginView.as_view(), name="login") 

Django2.0.1 urls配置:

    # 基于类方法实现登录,这里是调用它的方法path('login/', LoginView.as_view(), name="login")

6-5 form字段验证

验证最大长度,是否为空等一系列。

users下新建forms文件。

# encoding: utf-8
__author__ = 'mtianyan'
__date__ = '2018/1/10 0010 04:44'
# 引入Django表单 from django import forms # 登录表单验证 class LoginForm(forms.Form): # 用户名密码不能为空 username = forms.CharField(required=True) password = forms.CharField(required=True, min_length=5) 

定义好forms之后我们来使用它做验证。

def post(self, request): # 类实例化需要一个字典参数dict:request.POST就是一个QueryDict所以直接传入 # POST中的usernamepassword,会对应到form中 login_form = LoginForm(request.POST) #is_valid判断我们字段是否有错执行我们原有逻辑,验证失败跳回login页面 if login_form.is_valid(): # 取不到时为空,username,password为前端页面name值 user_name = request.POST.get("username", "") pass_word = request.POST.get("password", "") # 成功返回user对象,失败返回null user = authenticate(username=user_name, password=pass_word) # 如果不是null说明验证成功 if user is not None: # login_in 两参数:request, user # 实际是对request写了一部分东西进去,然后在render的时候: # request是要render回去的。这些信息也就随着返回浏览器。完成登录 login(request, user) # 跳转到首页 user request会被带回到首页 return render(request, "index.html") # 验证不成功跳回登录页面 # 没有成功说明里面的值是None,并再次跳转回主页面 else: return render(request, "login.html", {"msg": "用户名或密码错误! "}) 

完善错误提示

比如:既然表单都验证失败了,就不用显示密码出错了

mark

# 仅当用户真的密码出错时else:return render(request, "login.html",{"msg":"用户名或密码错误!"}) # 验证不成功跳回登录页面 # 没有成功说明里面的值是None,并再次跳转回主页面 else: return render( request, "login.html", { "login_form": login_form }) 

forms中的名称username和password必须和html中的一致。毕竟他是使用的request.POST
而request是从前面传过来的。

实例化LoginView时已经对于我们的字段进行了验证。

打上断点:

mark

debugf6运行到

mark

此时可以看到errors(ErrorDict)中的错误

mark

将form传回前端:

mark

前端中取值:

mark

给这个class加上errorput会显示红色外框。

mark

注意:写在class里面

将forms错误信息显示出来

<div class="error btns login-form-tips" id="jsLoginTips"> {% for key, error in login_form.errors.items %} {{ error }} {% endfor %} {{ msg }}</div> 
mark

  • 写了一个类继承Django的view,然后写了get post方法(get/post的if是Django替我们完成的)
  • 在url中调用Loginview的as_view方法需要加上括号,进行调用。
  • Django的form进行表单验证并把error值传到前台。
  • is_valid方法,验证表单

本小节完毕对应commit:

6-4 & 5 登录换用类继承view实现,使用Django form进行表单验证并把错误信息提示到前台。

6-6 session和cookie自动登录机制

我们本节来讲session和cookie

User1如何实现登录的。

cookie的存储

cookie是浏览器支持的一种本地存储方式。以dict,键值对方式存储。

{"sessionkey": "123"}

浏览器会自动对于它进行解析。

http请求是一种无状态的请求

用户向服务器发起的两次请求之间是没有状态的。也就是服务器并不知道这是同一个用户发的。

做到记住用户:

浏览器a在向服务器发起请求,服务器会自动给浏览器a回复一个id,浏览器a把id放到cookie当中,在下一次请求时带上这个cookie里的id值向浏览器请求,服务器就知道你是哪个浏览器发过来的了。

有状态请求(cookie)

mark

服务器a发回来的id会放到服务器a的域之下。不能跨域访问cookie。

使用浏览器随便打开一个网页,然后f12打开。

比如我使用的Chrome浏览器

mark

会找到存储在浏览器本地的cookie值

mark

点击clear all清空所有的cookie f5刷新页面,会发现又把这些cookie值进来。

如果将用户名和密码直接保存在cookie,可以实现最垃圾最简略版本的自动登录。

解决cookie放在本地不安全的问题(session)

用户在第一次请求后,浏览器回复的id既可以是用户的user id。
也可以一段任意的字符串,我们把它叫做session id

根据用户名和密码,服务器会采用自己的规则生成session id。这个session id保存在本地cookie。浏览器请求服务器会携带。

  • 输入用户名 & 密码
  • 调用 login(), 后端程序会根据用户名密码生成session id。保存在数据库中。
  • 用户登录之后,需要通过这个session id取出这些基本信息。
mark

Django的默认表中的session表就记录了用户登录时,后端我们Django为用户生成的sessionid

mark

可以看到session key value 和过期时间。

我们可以清空这张表的数据。运行项目进行登录。

mark

可以看到我们刚刚生成的session id。

此时通过f12查看浏览器在本地存储的session id。可以看到如下图和我们数据库中的一致。

mark

session_key 发到浏览器叫做session id

通过session id 用户访问任何一个页面都会携带,服务器就会认识。

Setting.py中,

mark

这个app会拦截我们每次的request请求,在request中找到session id,然后去数据表中进行查询。
然后通过session key 去找到session data。此时直接为我们取出了user。

在服务器返回浏览器的response中也会直接加上session id

cookie是浏览器本地存储机制,存在域名之下,存储不安全。
服务器在返回id时通过规则生成一串字符,并设置了过期时间。存储在服务器端(数据库)

文章: http://projectsedu.com/2016/10/17/django%E4%BB%8E%E8%AF%B7%E6%B1%82%E5%88%B0%E8%BF%94%E5%9B%9E%E9%83%BD%E7%BB%8F%E5%8E%86%E4%BA%86%E4%BB%80%E4%B9%88/

6-7 用户注册

拷贝注册页面进入template目录

书写我们对应要处理的view(RegisterView)

users/views.py

# 注册功能的view
class RegisterView(View): # get方法直接返回页面 def get(self, request): return render(request, "register.html", {}) 

配置对应的url

Django1.9.8 url配置如下:

from users.views import RegisterView# 注册urlurl("^register/", RegisterView.as_view(), name="register"), 

Django2.0.1 url配置如下

from users.views import RegisterView# 注册urlpath("register/", RegisterView.as_view(), name = "register" ) 

修改index页面中注册url

mark

此时访问首页发现可以成功跳转到注册页面

修改静态文件中static目录引用

关键步骤load staticfile

mark

然后修改路径为一个相对于static的相对路径

mark

他会自动根据setting中配置,为我们加上前缀

mark

如果我们把目录在setting中改到mystatic。url中会自动添加指定的前缀

可以看到可以访问成功。

mark

将目前的三个html中的静态文件全部修改目录

枯燥但是要有耐心。

这时候访问三个页面,查看样式是否完好。

验证码库实现验证码

https://github.com/mbi/django-simple-captcha

安装配置

workon mxonline3
pip install  django-simple-captcha
workon mxonline2
pip install  django-simple-captcha==0.4.6
  • Add captcha to the INSTALLED_APPS in your settings.py

  • Add an entry to your urls.py:

django1.9.8如下:

from django.conf.urls import url, include
urlpatterns += [url(r'^captcha/', include('captcha.urls')), ] 

django2.0.1如下;

    # 验证码urlpath("captcha/", include('captcha.urls')) 
makemigrations
migrate
mark

进入数据库查看生成的表

mark

mark

将验证码展示到页面

users/forms.py:

定义我们的register form:

# 引入验证码field
from captcha.fields import CaptchaField# 验证码form & 注册表单form class RegisterForm(forms.Form): # 此处email与前端name需保持一致。 email = forms.EmailField(required=True) # 密码不能小于5位 password = forms.CharField(required=True, min_length=5) # 应用验证码 captcha = CaptchaField() 

users/views.py

在我们的registerform中实例化并传送到前端:

# form表单验证 & 验证码
from .forms import LoginForm, RegisterForm# 注册功能的view class RegisterView(View): # get方法直接返回页面 def get(self, request): # 添加验证码 register_form = RegisterForm() return render(request, "register.html", {'register_form':register_form}) 

前端获取验证码值

mark

mark

找到上图验证码部分。修改为下图

mark

Forms中的field会生成不同的框。

mark

我们只有label但是前端可以查看到input框等,也就是Registerform会为我们生成输入框+验证码。

隐藏的字符串的框会被带到后台,由Django为我们进行验证。验证该验证码是否保存过。

mark

可以看得我们数据库中将这个hashkey进行了保存。这个key与验证码内容对应。

后台会把验证码值 和 hashkey进行联合查询。

编写register view的后台逻辑(RegisterView)

users/views.py的RegisterView中添加post方法:

    def post(self, request): # 实例化form register_form = RegisterForm(request.POST) if register_form.is_valid(): pass 
mark

mark

修改form表单提交方式与提交到哪个url

mark

前端的form提交加上对应的crsf token

刷新验证码是前端帮我们完成的:

//刷新验证码
function refresh_captcha(event){ $.get("/captcha/refresh/?"+Math.random(), function(result){ $('#'+event.data.form_id+' .captcha').attr("src",result.image_url); $('#id_captcha_0').attr("value",result.key); }); return false; } 

获取前端页面值并封装成一个user_profile对象,保存到数据库。

from django.contrib.auth.hashers import make_passwordif register_form.is_valid():user_name = request.POST.get("email", "") pass_word = request.POST.get("password", "") # 实例化一个user_profile对象,将前台值存入 user_profile = UserProfile() user_profile.username = user_name user_profile.email = user_name # 加密password进行保存 user_profile.password = make_password(pass_word) user_profile.save() pass 

发送邮件实现

setting中配置;

# 发送邮件的setting设置EMAIL_HOST = "smtp.qq.com"
EMAIL_PORT = 25
EMAIL_HOST_USER = "mxonline.mtianyan.cn" EMAIL_HOST_PASSWORD = " " EMAIL_USE_TLS= True EMAIL_FROM = "mxonline.mtianyan.cn" 

新建package后新建文件。

apps:utils/email_send.py:

# encoding: utf-8
from random import Random__author__ = 'mtianyan' __date__ = '2018/1/10 0010 20:47' from users.models import EmailVerifyRecord # 导入Django自带的邮件模块 from django.core.mail import send_mail # 导入setting中发送邮件的配置 from Mxonline2.settings import EMAIL_FROM # 生成随机字符串 def random_str(random_length=8): str = '' # 生成字符串的可选字符串 chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789' length = len(chars) - 1 random = Random() for i in range(random_length): str += chars[random.randint(0, length)] return str # 发送注册邮件 def send_register_eamil(email, send_type="register"): # 发送之前先保存到数据库,到时候查询链接是否存在 # 实例化一个EmailVerifyRecord对象 email_record = EmailVerifyRecord() # 生成随机的code放入链接 code = random_str(16) email_record.code = code email_record.email = email email_record.send_type = send_type email_record.save() # 定义邮件内容: email_title = "" email_body = "" if send_type == "register": email_title = "mtianyan慕课小站 注册激活链接" email_body = "请点击下面的链接激活你的账号: http://127.0.0.1:8000/active/{0}".format(code) # 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) # 如果发送成功 if send_status: pass 
mark

上图为qq邮箱开启smtp服务

点击生成授权码

mark

def post中加上发送邮件

users/views.py

# 发送邮件
from utils.email_send import send_register_eamil# 发送注册激活邮件 send_register_eamil(user_name, "register") 

点击注册提交,因为我们没有return。一直在转圈圈。

但是数据库中已经添加了字段。

mark

可以看到我们的邮件已经被发送到邮箱中。

如果注册成功返回login页面:不成功,返回register页面并报错。

完善错误提示。

找猫画虎:将login中的错误提示搬运到register中来。

  • register_form的报错信息。
mark

mark

  • 邮箱 & 密码 form验证
mark

完善用户值回填逻辑

mark

如果传回的有值则,显示传回来值。

密码也做同样操作

修改默认的激活状态为false

post方法中

            # 默认激活状态为falseuser_profile.is_active = False

书写处理激活的view。

# 激活用户的view
class ActiveUserView(View): def get(self, request, active_code): # 查询邮箱验证记录是否存在 all_record = EmailVerifyRecord.objects.filter(code = active_code) # 激活form负责给激活跳转进来的人加验证码 active_form = ActiveForm(request.GET) # 如果不为空也就是有用户 if all_record: for record in all_record: # 获取到对应的邮箱 email = record.email # 查找到邮箱对应的user user = UserProfile.objects.get(email=email) user.is_active = True user.save() # 激活成功跳转到登录页面 return render(request, "login.html", ) # 自己瞎输的验证码 else: return render(request, "register.html", {"msg": "您的激活链接无效","active_form": active_form}) 

配置用户激活的url并通过url提取到变量:

django1.9.8:

    # 激活用户urlurl(r'^active/(?P<active_code>.*)/$',ActiveUserView.as_view(), name= "user_active")

django2.0.1:

    # 激活用户urlre_path('active/(?P<active_code>.*)/', ActiveUserView.as_view(), name= "user_active")

这里通过?p将后面.*代表全部提取的正则,符合的内容传入参数active_code中/$代表以/$为结尾

mark

其他细节根据自己需要进行优化。

注册功能制作完毕。对应commit:

注册功能实现完毕,流程:注册,发邮件,激活,登录。对应6-6,7,8,9,10

原文学习来自简书,作者:天涯明月笙
链接:https://www.jianshu.com/p/9c621518d991

转载于:https://www.cnblogs.com/xinjie57/p/9232627.html

django+xadmin在线教育平台(十二)相关推荐

  1. django+xadmin在线教育平台慕学网(二)

    三.xadmin后台管理 3.1 .xadmin的安装 github下在xadmin源码:下载地址 下载完成之后,解压复制xadmin文件夹 3.2.xadmin配置 (1)新建python pack ...

  2. django+xadmin 在线教育网站(二)

    在之前我们已经把项目所需的基本配置,已配置,接下来是此项目的重点配置(xadmin),我们将用xadmin,实现快速搭建后台管理系统 首先是xadmin的安装,github下载 xadmin下载链接地 ...

  3. django+xadmin 在线教育网站(三)

    在此之前我们已成功的使用xadmin将后台管理系统搭建起来了,接下来,开始我们后台的功能处理 首先是登录功能 登录功能 (1)把html文件中index.html和login.html拷贝到templ ...

  4. Django搭建在线教育平台(一)

    一.环境搭建 安装mysql 安装python 安装navicat 二.虚拟环境virtualenv virtualenv优点: 使用不同应用开发环境独立 环境实际不影响其他应用,也不影响全局的Pyt ...

  5. Django打造在线教育平台_day_4: 找回密码

    1.form.py验证输入 from django import forms from captcha.fields import CaptchaFieldclass ForgetForm(forms ...

  6. Django+xadmin打造在线教育平台(十)

    目录 在线教育平台(一)      在线教育平台(二) 在线教育平台(三)      在线教育平台(四) 在线教育平台(五)      在线教育平台(六) 在线教育平台(七)      在线教育平台( ...

  7. 第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页...

    第三百八十九节,Django+Xadmin打造上线标准的在线教育平台-列表筛选结合分页 根据用户的筛选条件来结合分页 实现原理就是,当用户点击一个筛选条件时,通过get请求方式传参将筛选的id或者值, ...

  8. Django+xadmin 打造线上教育平台(二)登录-注册(重制)

    Django+xadmin 打造线上教育平台(二) 一.首页 1)views.py/index函数: def index(request):"""首页"&quo ...

  9. Django+xadmin打造在线教育平台(七)

    Django+xadmin打造在线教育平台(七)   代码 github下载 十.授课教师 10.1.讲师列表页 拷贝teacher-list.html和teacher-detail.html到tem ...

最新文章

  1. Vue引入百度地图,如何去掉左下角的版权logo百度等信息?
  2. 解决报错:Can't read private key和./build-aux/cksum-schema-check: Permission denied
  3. 如何自学python爬虫-零基础入门Python爬虫不知道怎么学?这是入门的完整教程
  4. 使用非常驻任务管理事件
  5. 2016 CCPC 杭州站 小结
  6. Spring boot学习整理
  7. stylish和Tampermonkey样式及脚本
  8. Java 多态,接口
  9. 大道至简——编程的精义
  10. sqlserver2008_是时候挥别 SQL Server 2008 了
  11. MVC入门小示例---淘宝商品的搜索和价格筛选
  12. Easyrecovery激活码生成器分享
  13. Android内核层驱动程序UAF漏洞提权实例
  14. android 获得屏幕方向,Android 获取设置屏幕横竖屏
  15. Python学习_2015年12月14日
  16. js(JavaScript)操作字符串的方法
  17. php 403 -禁止访问 访问被拒绝,HTTP 错误 403.6 - Forbidden 访问IP地址被拒绝
  18. Github高星项目!用Python开发的一个网易云音乐
  19. 我只想做我自己,最真实的自己!
  20. 虚拟机测试服务器最大带宽,利用VMware ESXi测量网络延迟 你了解多少

热门文章

  1. 什么是创新?如何创新?
  2. 1.5编程基础之循环控制 34 求阶乘的和
  3. 【软考高项】信息系统项目管理师 论文写作技巧分享 (上)
  4. Java学习之连接数据库
  5. WEB编程学习之Wordpress发送邮件
  6. html百度天气api,百度API 免费接口获取天气预报
  7. 【四】Java流程控制
  8. Qt工作笔记-ListWidget拖动(拖拽)到QGraphicsScene【补坑】【Qt视图框架补坑】
  9. Qt学习笔记-使用shape() 使得碰撞更加精确
  10. Qt creator5.7 OpenCV249之方框滤波(含源码下载)