一、项目前端模板的套用

1.为什么使用前端模板

因为我们开发ObCRM系统使用的是Django项目,而我们知道,Django框架是一个全面的重量级的框架,并不是全后端分离的,所以涉及到的页面需要我们用到前端的知识,但是我们并不是专业的前端工程师,很多页面的搭建对我们说还是有点吃力。

其实在很多实际工作中开发,前端页面都是通过网络上寻找相应的模板,这样就可以避免在前端样式上调整的时间浪费,我们只需要继承别人写好的模板文件来快速开发自己的前端页面,专心投入自己的后端开发代码中。

2.admin前端模板

刚我们说使用别人写好的模板文件,有利于我们快速开发项目;我们写的这个项目也是使用了git上一个开源的前端模板,大家可以去git搜索adminLTE,如果你没有用过,点击这里https://github.com/ColorlibHQ/AdminLTE,将代码下载到本地就可以愉快的使用了。

我们解压后得到一个AdminLTE-master文件夹,文件夹路径结构如下:

目录下的文件内容如上,一般比较规范的模板文件,核心的js和css代码会放在dist路径下。

首先,我们先配置项目使用的静态文件夹,在项目路径下新建statics文件夹,settings中配置静态文件的路径,

STATIC_URL = '/static/'STATICFILES_DIRS = [  # 项目静态文件的配置os.path.join(BASE_DIR,"statics")
]

其实我们使用模板文件就是使用它的核心js和css以及对应写好的html页面,我们这个项目中使用了adminLTE的一些其他html页面,也就是说还需要使用bowser_components、plugins文件,这里我就将这三个文件拷贝到statics下的新建adminlte文件夹下。

如下是我这个项目的静态文件目录结构

  • adminlte:用于存放模板的js和css文件
  • bootstrap:存放的bootstrap核心js和css
  • jquery:存放jquery文件
  • css:自己根据具体需求写的一些css文件
  • js:自己根据具体需求写的一些js文件
  • font:项目用到的字体文件

二、登录页面的实现

1.初始超级用户

还记得我们的ObCRM系统的用户表使用是django项目中user的扩展表把,为什么使用Django用户提供的user表来扩展呢?是因为我们想要使用Django框架内置的auth认证模块,auth认证模块可以密文存储用户密码,快速简便的查询用户信息进行验证。

auth模块知识点回顾点这里!:Django框架—auth认证模块

在实现登录功能之前,我们先要有一个用户账号,就作为我们项目的超级管理帐号把。创建账号的时候要注意,不能直接在数据库添加记录,因为这样账号密码是明文存储的。

创建超级用户的方式,是在django的manage环境下,执行如下命令

createsuperuser  # 要通过这个指令来创建用户,因为这个指令会将你的密码加密

我们创建一个超级用户,这里我创建的用户帐号密码:ryxiong,ryxiong520

2.登录页面实现

登录url设置

因为我么项目涉及到多应用,所以需要使用到路由分发,用户登录输入rbac应用,所以我们在项目下url设置路由分发,将用户登录的url分发到rbac应用下。

urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^rbac/', include("rbac.urls")),url(r'^customer/', include("customer.urls")),url(r'^education/', include("education.urls")),
]

rbac应用下创建urls.py

注意:我们项目中实现验证码登录的功能,所以配置登录url还需要配置验证码url

from django.conf.urls import url,include
from rbac.views import accounturlpatterns = [# 用户登录urlurl(r'^login/', account.Login.as_view(), name="login"),# 验证码urlurl(r'^get_auth_img/', account.GetAuthImg.as_view(), name="get_auth_img"),
]

视图函数

对于登录用到的验证码获取我单独提炼了一个文件,放在rbac应用下的utils文件中的auth_code.py文件

get_authcode_img函数的作用是生成随机字符串,并通过内存操作符中读取出来,存储在session中,这样每个用户就可以根据携带自己的用户验证码请求后端,而不会和别人的验证码冲突。

import os
import string
import random
from io import BytesIO
from PIL import Image,ImageDraw,ImageFont
from ObCRM import settings  # 项目中的settings文件,配置了BASEDIR路径,在这里无需关注def get_authcode_img(request):"""获取随机验证码,带干扰噪点,:param request: request请求,用于将验证码存放在session中:return: 返回验证码图片的数据内容"""def get_background_color():  # 定义一个获取图片背景/噪点颜色的函数,产生浅色color = tuple((random.choices(range(160,256),k=3)))return colordef get_content_color():  # 定义一个获取文字颜色的函数,产生深色color = tuple((random.choices(range(0,100),k=3)))return colorimg_obj = Image.new("RGB",(117,34),get_background_color())  # 创建一个图片对象draw_obj = ImageDraw.Draw(img_obj)  # 通过图片对象生成一个画笔对象font_path = os.path.join(settings.BASE_DIR,"statics","font","cerepf__.ttf")  # 获取字体,注意有些字体无法显示数字font_obj = ImageFont.truetype(font_path,32)  # 创建一个字体对象random_code = ''  # 用户验证的字符串all_char = string.ascii_letters+string.digitsfor i in range(4):a = random.choice(all_char)random_code += adraw_obj.text((22,-3),random_code,fill=get_content_color(),font=font_obj)width = 117height = 34# 添加噪线for i in range(5):  # 添加5条干扰线# 两个坐标点确定一条线x1 = random.randint(0,width)y1 = random.randint(0,height)x2 = random.randint(0,width)y2 = random.randint(0,height)draw_obj.line((x1,y1,x2,y2),fill=get_background_color())  # 画噪线# 添加噪点for i in range(30):draw_obj.point((random.randint(0,width),random.randint(0,height)),fill=get_background_color())f = BytesIO()  # 生成内存操作符-句柄img_obj.save(f,"png")  # 将图片存在内存中data = f.getvalue()# 获取句柄中的内容# # 存验证码方式:1.存在全局变量(不可取,多个用户会顶替)2.存在各自客户的session中# # 方式1# global valid_str# valid_str = random_code# 方式二,推荐request.session["authcode"] = random_codereturn data

rbac视图文件,我们在应用下创建了views文件夹,文件中新建account来处理帐号相关的视图。

from django import views
from django.contrib import auth
from django.http import JsonResponse
from django.shortcuts import (render, redirect, reverse, HttpResponse
)
from rbac.utils import authcode# 用户登录视图类
class Login(views.View):def get(self, request):# get请求返回登录页面return render(request, "login.html")def post(self, request):data = request.POST# 获取用户登录信息authcode = data.get("authcode")username = data.get("username")password = data.get("password")# 验证码不正确if request.session.get("authcode").upper() != authcode.upper():return JsonResponse({"status": "1"})else:# 使用django的auth模块进行用户名密码验证user = auth.authenticate(username=username, password=password)if user:# 将用户名存入session中request.session["user"] = usernameauth.login(request, user)  # 将用户信息添加到session中return JsonResponse({"status": "2"})else:return JsonResponse({"status": "3"})# 验证码视图类
class GetAuthImg(views.View):"""获取验证码视图类"""def get(self, request):data = authcode.get_authcode_img(request)print("验证码:",request.session.get("authcode"))return HttpResponse(data)

模板文件

系统的登录功能是通过ajax实现异步请求,后端验证数据,这种方式可以提高用户体验。

其次,登录页面使用的是adminLTE模板中的login页面,对页面进行自己的修改,login页面在adminLTE-master/pages/examples/login.html自取。

登录html页面,放在rbac应用下新建templates文件夹下。

{% load static %}
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>AliCRM | 登录</title><!-- Tell the browser to be responsive to screen width --><meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"><!-- Bootstrap 3.3.7 --><link rel="stylesheet" href="{% static 'adminlte/bower_components/bootstrap/dist/css/bootstrap.min.css' %}"><!-- Font Awesome --><link rel="stylesheet" href="{% static 'adminlte/bower_components/font-awesome/css/font-awesome.min.css' %}"><!-- Ionicons --><link rel="stylesheet" href="{% static 'adminlte/bower_components/Ionicons/css/ionicons.min.css' %}"><!-- Theme style --><link rel="stylesheet" href="{% static 'adminlte/dist/css/AdminLTE.min.css' %}"><!-- iCheck --><link rel="stylesheet" href="{% static 'adminlte/plugins/iCheck/square/blue.css' %}"></head>
<body class="hold-transition login-page">
<div class="login-box"><div class="login-logo"><a href=""><b>Ali</b>CRM</a></div><!-- /.login-logo --><div class="login-box-body"><p class="login-box-msg">请登录</p><form action="" method="post">{% csrf_token %}<div class="form-group has-feedback"><input type="text" class="form-control" placeholder="username" name="username"><span class="glyphicon glyphicon-user form-control-feedback"></span><span class="username-error" style="color:#b14442"></span></div><div class="form-group has-feedback"><input type="password" class="form-control" placeholder="Password" name="password"><span class="glyphicon glyphicon-lock form-control-feedback"></span><span class="password-error" style="color:#b14442"></span></div><div class="row"><div class="col-sm-7"><div class="form-group has-feedback"><input type="text" class="form-control" placeholder="验证码" name="authcode"><span class="glyphicon glyphicon-barcode form-control-feedback"></span></div></div><div class="col-sm-4"><img id="authImg" src="{% url 'get_auth_img' %}" alt="验证码"></div></div><div class="row"><div class="col-xs-8"><div class="checkbox icheck"><label><input type="checkbox"> 是否记住帐号</label></div></div><!-- /.col --><div class="col-xs-4"><button type="button" id="loginBtn" class="btn btn-primary btn-block btn-flat">登录</button></div><!-- /.col --></div></form><div class="social-auth-links text-center"><p>- OR -</p><a href="#" class="btn btn-block btn-social btn-facebook btn-flat"><i class="fa fa-facebook"></i>使用微信登录</a></div><!-- /.social-auth-links --><a href="#">忘记密码</a><br><a href="{% url 'register' %}" class="text-center">注册一个新账号!</a></div><!-- /.login-box-body -->
</div>
<!-- /.login-box --><!-- jQuery 3 -->
<script src="{% static 'jquery/jquery-3.4.1.js' %}"></script>
<!-- Bootstrap 3.3.7 -->
<script src="{% static 'adminlte/bower_components/bootstrap/dist/js/bootstrap.min.js' %}"></script>
<!-- iCheck -->
<script src="{% static 'adminlte/plugins/iCheck/icheck.min.js' %}"></script>
<script>$(function () {$('input').iCheck({checkboxClass: 'icheckbox_square-blue',radioClass: 'iradio_square-blue',increaseArea: '20%' /* optional */});});// 登录ajax请求$("#loginBtn").on("click", function () {var username = $("input[name=username]").val();var password = $("input[name=password]").val();var authcode = $("input[name=authcode]").val();var csrf_token = $("input[name=csrfmiddlewaretoken]").val();if (!username) {$(".username-error").text("帐号不能为空!")}if (!password) {$(".password-error").text("密码不能为空!")}if (!authcode) {$(".authcode-error").text("请输入验证码")}$.ajax({url: "{% url 'login' %}",type: 'post',data: {username: username,password: password,authcode: authcode,csrfmiddlewaretoken: csrf_token,},success: function (res) {if (res.status === "1") {$(".authcode-error").text("验证码错误!")}if (res.status === "2") {var href = location.search.slice(6);  //使用了auth的装饰器,会记录未登录用户想要访问的登录页面,登录成功后,会自动跳转过去if (href) {location.href = href  //登录成功,有目标地址} else {location.href = "{% url 'index' %}"  // 登录成功没有目标地址,跳转主页}}if (res.status === "3") {  // 帐号密码错误$(".username-error").text("账号或密码错误!")}}})});// 验证码刷新$("#authImg").on("click", function () {$("#authImg")[0].src += "?" // 点击事件刷新验证码图片})
</script>
</body>
</html>

注意:

该页面中的register和主页index还没有实现,所以路径反向解析会报错,可以先删除,以后在配置。

三、注册功能的实现

注册用户url配置

# 用户注册url
url(r'^register/', account.Register.as_view(), name="register"),

注册视图类

注册视图涉及到前端提取数据到后端,并需要保存在数据库,所以数据需要校验合法性,数据的合法性校验有两种方式。

  1. 在前端通过js中的re正则方式去校验
  2. 在后端校验数据的合法性,通过form组件

由于我们的前端水平啊,不堪一说,对我们来说也相对复杂,所以我们这里通过后端来校验数据的合法性,合法性校验也可以自己获取数据区较验,但是使用form组件来完成这个事情,更加高效,快速,准确。

既然要使用form那就需要先写一个form组件,这里关于rbac的form我们放在rbac/forms/formAuth.py文件中。

from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError# 注册form认证
class RegForm(forms.Form):"""定义注册帐号的form组件"""username = forms.CharField(label = "用户名",max_length=18,error_messages={"required":"内容不能为空","invalid":"格式错误","max_length":"用户名最长不超过18位"},widget=forms.TextInput(attrs={"class":"forms-control"}))password = forms.CharField(min_length=6,error_messages={"required": "内容不能为空","invalid": "格式错误","min_length": "密码不能少于6位"})r_password = forms.CharField(min_length=6,error_messages={"required": "内容不能为空","invalid": "格式错误","min_length": "密码不能少于6位"})email = forms.CharField(label="邮箱",error_messages={"required": "内容不能为空","invalid": "格式错误",},validators=[RegexValidator(r"^\w+@\w+\.com$", "邮箱格式不正确")])phone = forms.CharField(label="电话",error_messages={"required": "内容不能为空","invalid": "格式错误",},validators=[RegexValidator(r"^[0-9]{4,11}$","请输入正确的号码")])# 定义局部钩子def clean_password(self):# 校验密码的合法性,不能为纯数据password = self.cleaned_data.get("password")if password.isdecimal():raise ValidationError("密码不能为纯数字!")return passworddef clean_r_password(self):# 校验密码的合法性,不能为纯数据r_password = self.cleaned_data.get("r_password")if r_password.isdecimal():raise ValidationError("密码不能为纯数字!")return r_password# 定义全局钩子def clean(self):# 校验两次密码输入是否一致if self.cleaned_data.get("password") != self.cleaned_data.get("r_password"):self.add_error("r_password","两次密码输入不一致!")else:return self.cleaned_data# 重写init方法,来批量设置标签的样式def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)for field in self.fields:self.fields[field].widget.attrs.update({"class":"forms-control"})

注册视图函数

from rbac.forms import formAuth# 注册视图类
class Register(views.View):def get(self, request):# 注册页面的生成我们并没有用form,因为我们使用的别人的模板样式return render(request, "register.html")def post(self, request):# post请求提交注册数据data = request.POSTform_obj = formAuth.RegForm(data)  # 数据交给form实例化if form_obj.is_valid():  # 验证提交数据的合法性valid_data = form_obj.cleaned_datausername = valid_data.get("username")# 判断帐号是否已存在if models.UserInfo.objects.filter(username=username):# 如果存在,给form中的username字段添加一个错误提示。form_obj.add_error("username", "帐号已存在")return render(request, "register.html", {"form_obj": form_obj})else:# 帐号可用,去掉多余密码,在数据库创建记录del valid_data["r_password"]models.UserInfo.objects.create_user(**valid_data)  # 创建普通用户return redirect("login")else:# 数据验证不通过,返回页面和错误提示,保留数据return render(request, "register.html", {"form_obj": form_obj})

注册html页面

{% load static %}
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>AdminLTE 2 | Registration Page</title><!-- Tell the browser to be responsive to screen width --><meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"><!-- Bootstrap 3.3.7 --><link rel="stylesheet" href="{% static 'adminlte/bower_components/bootstrap/dist/css/bootstrap.min.css' %}"><!-- Font Awesome --><link rel="stylesheet" href="{% static 'adminlte/bower_components/font-awesome/css/font-awesome.min.css' %}"><!-- Ionicons --><link rel="stylesheet" href="{% static 'adminlte/bower_components/Ionicons/css/ionicons.min.css' %}"><!-- Theme style --><link rel="stylesheet" href="{% static 'adminlte/dist/css/AdminLTE.min.css' %}"><!-- iCheck --><link rel="stylesheet" href="{% static 'adminlte/plugins/iCheck/square/blue.css' %}"></head>
<body class="hold-transition">
<div class="register-box"><div class="register-logo"><a href=""><b>Ali</b><span class="small">CRM</span></a></div><div class="register-box-body" style="border: #bbb 1px solid;border-radius: 2px"><p class="login-box-msg">注册一个帐号</p><form action=".{% url 'register' %}" method="post" novalidate>{% csrf_token %}<div class="form-group has-feedback"><input type="text" class="form-control" placeholder="用户名" name="username"><span class="glyphicon glyphicon-user form-control-feedback"></span><span class="has-error">{{ form_obj.username.errors.0 }}</span></div><div class="form-group has-feedback"><input type="password" class="form-control" placeholder="密码" name="password"><span class="glyphicon glyphicon-lock form-control-feedback"></span><span class="has-error">{{ form_obj.password.errors.0 }}</span></div><div class="form-group has-feedback"><input type="password" class="form-control" placeholder="确认密码" name="r_password"><span class="glyphicon glyphicon-log-in form-control-feedback"></span><span class="has-error">{{ form_obj.r_password.errors.0 }}</span></div><div class="form-group has-feedback"><input type="email" class="form-control" placeholder="邮箱" name="email"><span class="glyphicon glyphicon-envelope form-control-feedback"></span><span class="has-error">{{ form_obj.email.errors.0 }}</span></div><div class="form-group has-feedback"><input type="text" class="form-control" placeholder="电话" name="phone"><span class="glyphicon glyphicon-phone form-control-feedback"></span></div><div class="row"><div class="col-xs-8"><div class="checkbox icheck"><label><input type="checkbox">我同意该<a href="#">条款</a></label></div></div><!-- /.col --><div class="col-xs-4"><button type="submit" class="btn btn-primary btn-block btn-flat">注册</button></div><!-- /.col --></div></form><div class="social-auth-links text-center"><p>- OR -</p><a href="#" class="btn btn-block btn-social btn-success btn-flat"><span class="glyphicon glyphicon-qrcode"></span><i class=""></i>微信登录</a></div><a href="{% url 'login' %}" class="text-center">已经拥有账号</a></div><!-- /.form-box -->
</div>
<!-- /.register-box --><!-- jQuery 3 -->
<script src="{% static 'adminlte/bower_components/jquery/dist/jquery.min.js' %}"></script>
<!-- Bootstrap 3.3.7 -->
<script src="{% static 'adminlte/bower_components/bootstrap/dist/js/bootstrap.min.js' %}"></script>
<!-- iCheck -->
<script src="{% static 'adminlte/plugins/iCheck/icheck.min.js' %}"></script>
<script>$(function () {$('input').iCheck({checkboxClass: 'icheckbox_square-blue',radioClass: 'iradio_square-blue',increaseArea: '20%' /* optional */});});
</script>
</body>
</html>

Django实战【三】—用户登录、注册实现相关推荐

  1. 小编程(三):用户登录注册界面开发及用户信息管理案例代码详解

    用户登录注册界面开发及用户信息管理案例详解 刚开始接触Android编程,这算是我写的第一个简单工程,主要功能有:用户登录.注册.注销.修改密码.记住密码共5个基本操作,其内容涉及到以下几点: 1:B ...

  2. 基于Servlet+JSP+JavaBean开发模式的用户登录注册

    基于Servlet+JSP+JavaBean开发模式的用户登录注册 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复 ...

  3. Codeigniter 用户登录注册模块

    Codeigniter 用户登录注册模块 以下皆是基于Codeigniter + MySQL 一.要实现用户登录注册功能,首先就要和MySQL数据库连接,操作流程如下: CI中贯彻MVC模型,即Mod ...

  4. javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册

    一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...

  5. javaweb学习总结(二十二):基于Servlet+JSP+JavaBean开发模式的用户登录注册

    一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...

  6. javaweb学习总结——基于Servlet+JSP+JavaBean开发模式的用户登录注册

    一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...

  7. java wed登录面 代码_JavaWeb实现用户登录注册功能实例代码(基于Servlet+JSP+JavaBean模式)...

    下面通过通过图文并茂的方式给大家介绍JavaWeb实现用户登录注册功能实例代码,一起看看吧. 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBea ...

  8. 【Web基础】用户登录注册案例

    4,用户登录注册案例 4.1 需求分析 需求说明: 完成用户登录功能,如果用户勾选"记住用户" ,则下次访问登录页面 自动 填充用户名密码 完成注册功能,并实现 验证码 功能 4. ...

  9. go 注册登录 mysql_golang实现用户登录注册的方法

    golang实现用户登录注册的方法 发布时间:2020-06-17 10:56:15 来源:亿速云 阅读:198 作者:Leah 这篇文章给大家分享的是golang实现用户登录注册的方法,相信大部分人 ...

  10. PHP+MySQL实现用户登录注册API接口

    最近在学习PHP后台相关知识,利用PHP连接MySQL数据库实现了一个简单的用户登录注册及修改密码的API接口,接口为标准的json输出,本地验证通过.功能比较简单,不过也自己摸索了挺长时间,期间各种 ...

最新文章

  1. 利用计算机进行机械设计属于什么,计算机技术机械设计应用
  2. linux 守护进程 失败,Linux守护进程
  3. BZOJ 3105:[cqoi2013]新Nim游戏
  4. 打印Java数组的最简单方法是什么?
  5. python dlib学习(十):换脸
  6. 选择排序法python详解-Python选择排序算法(三)
  7. proe输入数字时成双出现_天猫双11花呗可提额,支付宝输入几个数字,试试就知道...
  8. 多项式乘法:练习总结
  9. 【虚拟主机篇】asp页面实现301重定向方法
  10. 第十一节: EF的三种模式(一) 之 DBFirst模式(SQLServer和MySQL两套方案)
  11. mysql中将int转为_mysql – 将int转换为varchar
  12. 如何确定你的伴侣真的爱你?复杂数学公式告诉你
  13. SQL Server 锁升级阈值
  14. ASP.NET AJAX深入浅出系列课程(10):基于Microsoft AJAX Library扩展客户端组件.zip(10.77 MB)...
  15. 红米骁龙855旗舰关键细节曝光:256G ROM+GPU超频模式
  16. 如何手工突破网吧的种种限制(转)
  17. 设置Windows系统双网卡同时上内外网
  18. el-select默认选中第一个,设置默认值
  19. 如何让html 兼容IE和chrome,chrome兼容模式如何切换成IE兼容模式_chrome兼容模式切换成IE兼容模式的方法-系统城...
  20. vsftp日志文件汉字_为何手机存储空间还没用就快满了?删掉这些隐藏冗余文件满血复活...

热门文章

  1. 在vue中 鼠标移入 切换背景图片 移出时再次切换图片
  2. 基于微信小程序的校园跑腿系统-计算机毕业设计
  3. 微信 服务器 台,2W台服务器的微信过载控制系统.docx
  4. 【html】 把 a 标签的下滑线去掉
  5. 3600000毫秒等于多少小时_将秒转换为(小时:分钟:秒:毫秒)时间的最佳方法是什么?...
  6. Java中比较数字的大小
  7. 一个合格程序员该做的事情,你做好了吗?
  8. Java中的length,length()和size()
  9. 央视:乐视网是创业失败还是涉嫌欺诈?
  10. 目前SEP 离线升级包下载及升级方法