本项目采用django自带的数据库

项目文件

  

models.py

 from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here. class Userinfo(AbstractUser):
email = models.EmailField()

settings.py

 AUTH_USER_MODEL='app01.Userinfo'#自定义认证表
LOGIN_URL='/login/'#指定认证失败的跳转页面 STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static_files')
]

settings.py

views.py

 from django.shortcuts import render, HttpResponse, redirect
from django import forms#django的form组件
from django.core.validators import RegexValidator#form组件中的validators自带校验器
from django.core.exceptions import ValidationError#错误
import re
from app01 import models
from django.http import JsonResponse#Json响应数据类型
from django.urls import reverse#url反向解析
from django.contrib import auth#django内置认证系统
from django.contrib.auth.decorators import login_required#认证装饰器 # Create your views here.
#自定义校验函数
def name_valid(value):
name_re = re.compile(r'^[\d]+')
ret = name_re.match(value)
if ret:
raise ValidationError('用户名不能以数字开头!') #注册form组件
class RegisterForm(forms.Form):
name = forms.CharField(
required=True,
label='用户名:',
min_length=6,
max_length=32,
help_text='只能有字母数字下划线组成,且不能以数字开头,长度6到32位!',
# initial='admin123_',
error_messages={
'required': '用户名不能为空!',
'min_length': '长度不能少于6位!',
'max_length': '长度不能超过32位!',
},
validators=[RegexValidator(r'^[a-zA-Z0-9_]+$', '用户名只能包含字母数字下划线!'), name_valid],
)
password = forms.CharField(
required=True,
label='密码:',
min_length=6,
max_length=32,
help_text='长度6到32位!',
initial='',
error_messages={
'required': '密码不能为空!',
'min_length': '长度不能少于6位!',
'max_length': '长度不能超过32位!',
},
widget=forms.PasswordInput(render_value=True),
)
r_password = forms.CharField(
required=True,
label='确认密码:',
min_length=6,
max_length=32,
help_text='长度6到32位!',
initial='',
error_messages={
'required': '密码不能为空!',
'min_length': '长度不能少于6位!',
'max_length': '长度不能超过32位!',
},
widget=forms.PasswordInput(render_value=True),
)
email = forms.EmailField(
required=True,
label='邮箱',
error_messages={
'required': '邮箱不能为空!',
'invalid':'邮箱格式不正确!'
}
)
#全部字段添加样式
def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({'class': 'form-control'})
#局部钩子
def clean_name(self):
pass
return self.cleaned_data.get('name') def clean_password(self):
pass
return self.cleaned_data.get('password') def clean_r_password(self):
pass
return self.cleaned_data.get('r_password') def clean_email(self):
pass
return self.cleaned_data.get('email')
#全局钩子
def clean(self):
password = self.cleaned_data.get('password')
r_password = self.cleaned_data.get('r_password')
if password != r_password:
self.add_error('r_password', '两次密码不一致!')
raise ValidationError('两次密码不一致!')
else:
return self.cleaned_data # 注册
def register(request):
if request.method == 'GET':
register_obj = RegisterForm()
return render(request, 'register.html', {'register_obj': register_obj})
elif request.method == 'POST':
data = request.POST
# print(data)
register_obj = RegisterForm(data)
if register_obj.is_valid():
user_obj = register_obj.cleaned_data
print(user_obj)
username = user_obj.get('name')
password = user_obj.get('password')
email = user_obj.get('email') if not models.Userinfo.objects.filter(username=username).exists():
new_obj = models.Userinfo.objects.create_user(username=username, password=password, email=email)
print(f'新用户{username}注册成功!')
return redirect('login')
else:
register_obj.add_error('name', '用户名已存在!')
return render(request, 'register.html', {'register_obj': register_obj}) else:
return render(request, 'register.html', {'register_obj': register_obj}) #登录页面的ModelForm组件(本次未使用)
'''
# class LoginForm(forms.ModelForm):
# class Meta:
# model = models.Userinfo # 指定类
# # fields='__all__'
# # exclude=[] #排除字段
# fields = ['username', 'password'] # 设置的字段
# labels = { # 标签名
# 'username': '用户名:',
# 'password': '密码:'}
# error_messages = { # 错误信息
# 'username': {'required': '用户名不能为空!'},
# 'password': {'required': '密码不能为空!'},
# }
# widgets = { # 插件
# 'username': forms.TextInput({"class": "form-control"}),
# 'password': forms.TextInput({"class": "form-control"}),
#
# }
# # def clean_username(self):
# # pass
# # return self.cleaned_data.get('username')
# # def clean(self):
# # pass
# # return self.cleaned_data
# # def __init__(self,*args,**kwargs):
# # super().__init__(*args,**kwargs)
# # for field in self.fields:
# # self.fields[field].widget.attrs.update({'class':'form-control'}) ''' #随机验证码
def get_cverification_code(request):
import os
from crmtest import settings
import random
def get_random_color():
'''
随机颜色
:return: rgb颜色
'''
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image, ImageDraw, ImageFont#要先安装pillow模块:pip install pillow
img_obj = Image.new('RGB', (120, 40), get_random_color())#实例化图片对象
draw_obj = ImageDraw.Draw(img_obj)#创建图片 font_path = os.path.join(settings.BASE_DIR, r'static_files\fonts\BRUX.otf')#字体路径(字体自己下载)
print('>>>>', font_path)
# font_obj = ImageFont.truetype(font_path, 26)#路径拼接注意不能有中文,否则报错
font_obj = ImageFont.truetype(r'static_files/fonts/BRUX.otf', 26) #相对路径r'static_files/fonts/BRUX.otf'
# font_obj = ImageFont.load_default().font#系统默认字体
sum_str = ''
for i in range(6):#生成随机的字母数字组合
a = random.choice([str(random.randint(0, 9)), chr(random.randint(97, 122)),
chr(random.randint(65, 90))]) # 4 a 5 D 6 S
sum_str += a
print(sum_str)
draw_obj.text((12, 2), sum_str, fill=get_random_color(), font=font_obj) width = 120
height = 40
# 添加噪线
for i in range(5):#循环一次就是一条线:两点确定一条
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
# # 添加噪点
for i in range(10):
# 这是添加点,50个点
draw_obj.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
# 下面是添加很小的弧线,看上去类似于一个点,50个小弧线
x = random.randint(0, width)
y = random.randint(0, height)
draw_obj.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color()) from io import BytesIO#生成的图片格式指定和存在位置(缓存)
f = BytesIO()
img_obj.save(f, 'png')
data = f.getvalue() # 验证码对应的数据保存到session里面
request.session['valid_str'] = sum_str return HttpResponse(data) # 登录
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
# print(request.POST)
username = request.POST.get('username')
password = request.POST.get('password')
cverification_code=request.POST.get('cverification_code') if cverification_code.upper()==request.session.get('valid_str').upper(): user_obj = auth.authenticate(username=username, password=password)
print(user_obj)
if user_obj:
auth.login(request, user_obj)
return JsonResponse({'status': 1, 'url': reverse('index')})
else:
return JsonResponse({'status': 0, 'url': '账号或密码有误!'})
else:
return JsonResponse({'status': 0, 'url': '验证码输入有误!'}) #状态认证的首页访问(使用装饰器认证状态失败,会自动跳转一个路径,可以在settings中配置指定LOGIN_URL='/login/')
#同时在页面的请求路径会自动加上'?next=/index/'(当前页面路径),
# 借此可以在前端通过location.search获取后slice切边获取路径,登录成功之后在success回调函数location.href指向该路径,自动跳转访问的页面
@login_required
def index(request):
# if request.user.is_authenticated:
print(request.user)
if request.method == 'GET':
return render(request, 'index.html')
# else:
# return redirect('login') #不加装饰器的方法判断状态
'''
def index(request):
if request.user.is_authenticated:
print(request.user)
if request.method == 'GET':
return render(request, 'index.html')
else:
return redirect('login')
''' #注销
def logout(request):
auth.logout(request)
return redirect('login') #修改密码
def reset_psd(request):
if request.user.is_authenticated:
if request.method == 'GET':
return render(request, 'reset_psd.html')
elif request.method == 'POST':
old_password = request.POST.get('old_password')
new_password = request.POST.get('new_password')
r_new_password = request.POST.get('r_new_password')
# ret=request.user.check_password(old_password)
# print(ret)
if request.user.check_password(old_password):
if new_password == r_new_password:
request.user.set_password(new_password)
request.user.save()
return JsonResponse({'status': True, 'info': '操作成功!', 'url': reverse('index')})
else:
return JsonResponse({'status': False, 'info': '两次新密码不一致!', 'url': ''})
else:
return JsonResponse({'status': False, 'info': '操作失败:原密码输入有误!', 'url': ''})
return JsonResponse({'status': False, 'info': '操作失败!', 'url': ''}) else:
return redirect('login')

views.py

urls.py

 from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/', views.register, name='register'),
url(r'^login/', views.login, name='login'),
url(r'^index/', views.index, name='index'),
url(r'^logout/', views.logout, name='logout'),
url(r'^reset_psd/', views.reset_psd, name='reset_psd'),
url(r'^get_cverification_code/', views.get_cverification_code, name='get_cverification_code'),#随机验证码 ]

urls.py

templates

register.html

 {% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <title>用户注册</title>
</head>
<body style="background-image: url('{% static 'images/register_bg.gif' %}');background-size: cover">
<div class="container">
<div class="row">
<div class="col-xs-6 col-xs-offset-3" style="margin-top: 12%;">
<div class="container-fluid" style="background-color: rgba(255,255,255,0.2);border-radius: 5%">
<div class="row">
<h2 class="text-left col-xs-8 text-primary">新用户注册:</h2>
</div>
<div class="row" >
<form action="{% url 'register' %}" method="post" novalidate class="form-horizontal">
{% csrf_token %}
{% for field in register_obj %}
<div class="form-group" >
<label for="{{ field.id_for_label }}"
class="col-xs-3 control-label" >{{ field.label }}</label>
<div class="col-xs-7">
{{ field }}
<div style="height: 10px;" class="text-danger">{{ field.errors.0 }}</div>
</div>
</div>
{% endfor %}
<div class="form-group">
<div class="col-sm-7 col-xs-offset-3">
<span class="col-xs-10 text-success text-center"
style="line-height: 200%">已有账号,请<a href="{% url 'login' %}">登录</a>!</span>
<input type="submit" class="btn btn-success btn-sm col-xs-2 pull-right"> </div>
</div>
</form>
</div>
</div>
</div>
</div>
</div> </body>
<script src="{% static 'jquery-3.4.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</html>

register.html

  login.html

 {% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<title>用户登录</title>
</head>
<body style="background-image: url('{% static "images/login_bg.jpg" %}');background-size: cover">
<div>
<div class="container">
<div class="row">
<div class='col-xs-4 col-xs-offset-4'>
<div class="row" style="margin-top: 50%;background-color: rgba(255,255,255,0.2 );border-radius: 3%">
<div class="row c1">
<h2 class=" col-xs-6 text-primary" style="margin-bottom: 30px">用户登录</h2>
</div>
<div class="row">
<div class="form-group" style="height: 60px;">
<label for="username" class="col-xs-3 control-label text-right">用户名:</label>
<div class="col-xs-8">
<input type="text" class="form-control" id="username">
<div class="text-danger"></div>
</div>
</div>
<div class="form-group" style="height: 60px;">
<label for="password" class="col-xs-3 control-label text-right">密码:</label>
<div class="col-xs-8">
<input type="password" class="form-control" id="password">
<div class="text-danger"></div>
</div>
</div> <div class="form-group" style="height: 60px;">
<label for="code" class="col-xs-3 control-label text-right">验证码:</label>
<div class="col-xs-4">
<input type="text" class="form-control" id="code">
<div class="text-danger"></div>
</div>
<div class="col-xs-5" style="padding-left: 0"><img src="{% url 'get_cverification_code' %}"
alt="" id="cverification_code"></div>
</div> <div class="form-group" style="height: 60px;">
{% csrf_token %}
<div class="col-xs-8 col-xs-offset-3">
<a href="{% url 'register' %}">
<button class="btn btn-primary col-xs-offset-2" id="register">注册</button>
</a>
<button class="btn btn-success col-xs-offset-2" id="submit">登录</button>
<div class=" text-danger"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div>
</body>
<script src="{% static 'jquery-3.4.1.js' %}"></script>
<script src="{% static 'jquery-cookie-1.4.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script>
$(function () { $('#cverification_code').on('click',function () {
var src='{% url "get_cverification_code" %}?temp='+Math.random();
console.log(src);
$('#cverification_code').attr('src',src);
}); $('#username').blur(function () {
if (username !== '') {
$('#username').next().text('');
}
});
$('#password').blur(function () {
if (username !== '') {
$('#password').next().text('');
}
});
$('#code').blur(function () {
if (username !== '') {
$('#code').next().text('');
}
});
$('#username').focus(function () {
if (username !== '') {
$('#submit').next().text('');
}
});
$('#password').focus(function () {
if (username !== '') {
$('#submit').next().text('');
}
});
$('#code').focus(function () {
if (username !== '') {
$('#code').next().text('');
}
}); $('#submit').click(function () { var username = $('#username').val().trim();
var password = $('#password').val().trim();
var cverification_code = $('#code').val().trim();
console.log(cverification_code);
console.log(cverification_code.length); if (username === '' || password === '' || cverification_code.length !== 6) {
if (username === '') {
$('#username').next().text('用户名不能为空!');
}
;
if (password === '') {
$('#password').next().text('密码不能为空!')
}
;
if (cverification_code.length !== 6) {
$('#code').next().text('验证码为6位!');
}
;
console.log(cverification_code.length);
if (cverification_code.length !== 6) {
$('#code').next().text('验证码为6位!');
return false
}
; } else {
$.ajax({
url: '{% url 'login' %}',
type: 'POST',
headers: {'X-CSRFToken': $.cookie('csrftoken')},
data: {
'username': username,
'password': password,
'cverification_code': cverification_code, },
success: function (request) {
console.log(request);
if (request.status === 1) {
location.href = request.url;
} else {
$('#submit').next().text(request.url);
}
}
})
} })
})
</script>
</html>

login.html

  index. Html

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>index</h1>
<a href="{% url 'logout' %}"><h6>注销</h6></a>
<a href="{% url 'reset_psd' %}">修改密码</a>
</body>
</html>

login.html

  reset_psd.html

 {% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<title>修改密码</title>
</head>
<body>
<div><h3>当前用户:{{ username }}</h3> <p>请输入原密码:<input type="password" id="old_password"></p>
<P>请输入新密码:<input type="password" id="new_password"></P>
<p>请确认新密码:<input type="password" id="r_new_password"></p>
{% csrf_token %}
<p><button class="btn btn-success" id="submit">保存</button></p> </div>
</body>
<script src="{% static 'jquery-3.4.1.js' %}"></script>
<script src="{% static 'jquery-cookie-1.4.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script>
$(function () {
$('#submit').click(function () {
var old_password=$('#old_password').val().trim();
var new_password=$('#new_password').val().trim();
var r_new_password=$('#r_new_password').val().trim(); if(old_password===''||new_password==='' || r_new_password===''){
alert('不允许有空!');
return false
}; if(new_password!==r_new_password){
alert('两次输入的新密码不一致,请重新确认输入!');
return false
}; $.ajax({
url:'{% url "reset_psd" %}',
type:'post',
headers:{'X-CSRFToken':$.cookie('csrftoken')},
data:{
old_password:old_password,
new_password:new_password,
r_new_password:r_new_password,
},
success:function (response) {
if(response.status===true){
alert(response.info);
location.href=response.url;
}
else {
alert(response.info)
}
} }
)
})
})
</script>
</html>

reset_psd.html

form组件注册ajax登录auth认证及验证码的更多相关文章

  1. Django-利用Form组件和ajax实现的注册

    利用Form组件和ajax实现的注册 一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面 ...

  2. Django【第23篇】:利用Form组件和ajax实现的注册

    利用Form组件和ajax实现的注册 一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面 ...

  3. 2.1博客系统 |基于form组件和Ajax实现注册登录

    基于forms组件和Ajax实现注册功能 1 基于forms组件设计注册页面 --点击头像 === 点击input --头像预览: 修改用户选中的文件对象:获取文件对象的路径:修改img的src属性, ...

  4. 利用Form组件和ajax实现的注册

    一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...

  5. Django框架之Ajax和form组件

    一.Django框架之查漏补缺 1)models,字段概况 name = models.CharField(max_length=) age = models.IntegerField() price ...

  6. python框架之Django(10)-Form组件

    介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入 ...

  7. Django中 基于form的注册,基于ajax的登录

    1 form.py中写register的的form组件 from django import forms class Register(forms.Form): # 注册的form username ...

  8. 认证登录装饰器与form组件的使用

    def auth(func): '''制作登录认证的装饰器''' def inner(request,*args,**kwargs): user_info=request.session.get(se ...

  9. BBS-基于forms组件和ajax实现注册功能

    http://www.cnblogs.com/yuanchenqi/articles/7638956.html 1.设计注册页面 views.py from django import forms c ...

随机推荐

  1. Selenium常见报错问题(1)- 先来认识下selenium常见异常类

    如果你在跑selenium脚本时,需要某些异常不知道怎么解决时,可以看看这一系列的文章,看看有没有你需要的答案 https://www.cnblogs.com/poloyy/category/1749 ...

  2. 以命令行界面启动 Ubuntu

    1. /etc/default/grub 将GRUB_CMDLINE_LINUX_DEFAULT一行中改为"quiet splash 3" 2. update-grub 3. 重启

  3. java中interrupt,interrupted和isInterrupted的区别

    文章目录 isInterrupted interrupted interrupt java中interrupt,interrupted和isInterrupted的区别 前面的文章我们讲到了调用int ...

  4. ERC20 Short Address Attack

    ERC20 Short Address Attack 什么是ERC20 Application Binary Interface(ABI) ERC20 Short Address Attack 开始攻 ...

  5. 小米Note 10 Lite海外发布 无缘中国市场

    [TechWeb]5月1日消息,昨日晚间,小米Note 10 Lite在海外亮相.小米市场部副总经理臧智渊在微博透露,小米Note 10 Lite 6GB+64GB版售价349欧元(约合人民币2700 ...

  6. 【Linux常见命令】head命令

    head - output the first part of files 读取文件的前n行,默认前10行 语法: head [OPTION]... [FILE]... 参数: -n 数字 显示前n行 ...

  7. MySQL5.7中InnoDB不可不知的新特性

    讲师介绍  赖铮 Oracle InnoDB团队 Principle Software Developer 曾任达梦.Teradata高级工程师,主要负责研发数据库执行引擎和存储引擎,十年以商数据库内 ...

  8. qcow2快照原理

    关键术语:cluster 一个Qcow2 img文件由固定大小的单元组成,该单元称为cluster,默认大小为65536bytes/64Ksector 数据块读写的最小单元,大小为512字节host ...

  9. vue跳转的两种方法

    1 标签跳转 <router-link to='two'><button>点我到第二个页面</button></router-link> 2 点击事件跳 ...

  10. 记一次jackson序列化Boolean的坑

    @Data public class CouponTemplateDto { /** * 优惠券类型id */ private Long couponTypeId; /** * 优惠券模板id */ ...