form组件注册ajax登录auth认证及验证码
本项目采用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认证及验证码的更多相关文章
- Django-利用Form组件和ajax实现的注册
利用Form组件和ajax实现的注册 一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面 ...
- Django【第23篇】:利用Form组件和ajax实现的注册
利用Form组件和ajax实现的注册 一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面 ...
- 2.1博客系统 |基于form组件和Ajax实现注册登录
基于forms组件和Ajax实现注册功能 1 基于forms组件设计注册页面 --点击头像 === 点击input --头像预览: 修改用户选中的文件对象:获取文件对象的路径:修改img的src属性, ...
- 利用Form组件和ajax实现的注册
一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...
- Django框架之Ajax和form组件
一.Django框架之查漏补缺 1)models,字段概况 name = models.CharField(max_length=) age = models.IntegerField() price ...
- python框架之Django(10)-Form组件
介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入 ...
- Django中 基于form的注册,基于ajax的登录
1 form.py中写register的的form组件 from django import forms class Register(forms.Form): # 注册的form username ...
- 认证登录装饰器与form组件的使用
def auth(func): '''制作登录认证的装饰器''' def inner(request,*args,**kwargs): user_info=request.session.get(se ...
- BBS-基于forms组件和ajax实现注册功能
http://www.cnblogs.com/yuanchenqi/articles/7638956.html 1.设计注册页面 views.py from django import forms c ...
随机推荐
- chcp437 转换英语,在西班牙语系统中无效
https://social.technet.microsoft.com/Forums/en-US/9c772011-5094-4df0-bf73-7140bf91673b/chcp-command- ...
- Pascal 字符串
Dancing with Strings http://baskent.edu.tr/~tkaracay/etudio/ders/prg/pascal/PasHTM1/pas/pasl1007.htm ...
- Prometheus+Grafana 监控 Docker
cAdvisor (Container Advisor) :用于收集正在运行的容器资源使用和性能信息. https://github.com/google/cadvisor Prometheus(普罗 ...
- 徐州H
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) #defi ...
- webpack前端构建angular1.0!!!
webpack前端构建angular1.0 Webpack最近很热,用webapcak构建react,vue,angular2.0的文章很多,但是webpack构建angualr1.0的文章找来找去也 ...
- vue+elementUI实现权限的部门管理
回头看写过的项目,发现以前感觉有难度的地方,现在想想很简单,在此记录一下,不对的地方欢迎吐槽!!! 复制代码 1.实现效果 2.需求分析 主要用于平台各个部门不同权限的操作,将指定的账号放到对应的权限 ...
- stl的stack在开发中的应用
栈有后进先出特点,我们可以用它来暂时保存数据,在画板开发中,我用到了栈来保存用户的每一步操作,当用户点击撤销时可以把图像从栈里面取出,然后恢复.浏览器的前进和后退也是这个原理,只是它保存的是网页罢了. ...
- Windows 10 MSDN官方原版ISO镜像(简体中文)下载
http://www.heu8.com/2800.html 硬件要求如下:处理器:1 GHz 或更快的处理器或 SoC RAM:1 GB(32 位)或 2 GB(64 位) 硬盘空间:16 GB(32 ...
- tr标签使用hover的box-shadow效果不生效
先说问题: 这是大致的HTML结构 <table cellpadding="0" cellspacing="0"> <thead> &l ...
- nginx代理vue项目
很多项目的前端都使用vue编写的,在项目上线部署的时候,有些项目要求把前端页面和后台服务部署在不同的服务器,这就要求使用nginx代理,本文就来讲讲vue项目怎么使用nginx代理. 项目github ...