Django---Blog系统开发之注册页面(验证码&ajax发送文件)
前端页面及渲染:
静态文件的配置:setting.py:
static 文件放在app下
STATIC_URL = '/static/' STATIC_ROOT = (
os.path.join(BASE_DIR,'blog01/static')
)
static目录结构:

配置URL:
from django.conf.urls import url,include
from django.contrib import admin
from blog01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog01.urls')),
url(r'^$',views.index),
url(r'^index/',views.index),
url(r'^register',views.register),
url(r'login',views.log_in),
url(r'valid_code',views.valid_code),
url(r'logout',views.log_out),
url(r'set_password',views.set_password),
]
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎注册</title>
<script src="{% static 'jquery-3.2.1.js' %}"></script>
<link href="{% static 'bootstrap/css/bootstrap.css' %}" rel="stylesheet">
<link href="{% static 'bootstrap/css/mystyle.css' %}" rel="stylesheet">
</head>
<body>
<div class="container register_container">
<div class="row">
<div class="col-sm-5 col-sm-offset-1">
<form>
{% csrf_token %}
<div class="form-group">
<label for="username">请输入用户名</label>
<span class="user_error"></span>
{{ form_obj.username }}
</div>
<div class="form-group register_avatar">
<label for="avatar">请选择头像</label>
<img src="{% static 'imag/q.png' %}" class="register_avatar_img">
<input type="file" class="register_avatar_input" id="avatar" name="avatar">
</div>
<div class="form-group">
<label for="password">请输入密码</label>
<span class="password_error"></span>
{{ form_obj.password }}
</div>
<div class="form-group">
<label for="re_password">请再次输入密码</label>
<span class="re_password_error"></span>
{{ form_obj.re_password }}
</div>
<div class="form-group">
<label for="email">请输入邮箱</label>
<span class="email_error"></span>
{{ form_obj.email }}
</div>
<div class="form-group">
<label for="id_valid_code">验证码</label>
<span class="valid_code_error"></span>
<div class="row">
<div class="col-sm-6">
{{ form_obj.valid_code }}
</div>
<div class="col-sm-6">
<img src="/valid_code/" alt="" class="valid_img">
<a class="img_refresh">刷新</a>
</div>
</div>
</div>
<button type="button" class="btn btn-default register_button">提交</button>
</form>
</div>
<div class="col-sm-3 col-sm-offset-1">
<img src="{% static 'imag/iamg_register.png' %}" alt="" >
</div>
</div>
</div>
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
<script src="{% static 'bootstrap/js/myaction.js' %}"></script>
</body>
</html>
register.html
/*for register html*/
.register_container{
margin-top: 40px;
}
.re_password_error,.user_error,.email_error,.password_error,.re_password_error,.valid_code_error
{color: red;
margin-left: 50px}
/*调input输入框和img标签的位置,保证两者完全重合*/
.register_avatar{position: relative;
width: 80px;
height: 80px}
.register_avatar_img,.register_avatar_input{position: absolute;
left: 80px;
top: 0;
width: 80px;
height: 80px}
/*设置透明度,只显示图片。如果设置display=none的话,物理位置会消失,不能点击上传图片*/
.register_avatar_input{opacity: 0}
mystyle
//失入焦点时判断密码是否一致
$('#id_re_password').blur(function () {
var pwd = $('#password').val();
var re_pwd = $(this).val();
if (pwd != re_pwd){
var error_message = '密码不一致';
$('.password_error_message').text(error_message)
}
}); //得到焦点时清空错误提示信息
$('#id_re_password').focus(function () {
$('.password_error_message').text(' ')
}); //ajax 发送注册数据
$('.register_button').click(function () { var formData = new FormData(); var csrfmiddlewaretoken = $("[name='csrfmiddlewaretoken']").val();
var username = $('#id_username').val();
var password = $('#id_password').val();
var re_password = $('#id_re_password').val();
var email = $('#id_email').val();
var valid_code = $('#id_valid_code').val();
var avatar = $('#avatar')[0].files[0]; formData.append("csrfmiddlewaretoken",csrfmiddlewaretoken);
formData.append('username',username);
formData.append('password',password);
formData.append('re_password',re_password);
formData.append('email',email);
formData.append('valid_code', valid_code);
formData.append('avatar',avatar); $.ajax({
url:'/register/',
type:'POST',
data:formData, //使用formadate,必须设置contentType,processDate为false
contentType:false,
processData:false,
success:function (data) {
data = JSON.parse(data);
if (data['state']){
location.href = '/login/'
}
else { $('.user_error').text(data['error_message']['username']);
$('.password_error').text(data['error_message']['password']);
$('.email_error').text(data['error_message']['email']);
$('.valid_code_error').text(data['error_message']['valid_code']);
if (data['error_message']['re_password']) {
$('.re_password_error').text(data['error_message']['re_password']);
}
else {
$('.re_password_error').text(data['error_message']['__all__']);
}
} }
})
}); //头像预览 $('.register_avatar_input').change(function () {
var reader = new FileReader();
var file = $('.register_avatar_input')[0].files[0];
reader.readAsDataURL(file);
reader.onload=function () {
$('.register_avatar_img')[0].src = this.result;
console.log($('.register_avatar_img')[0])
} }); //验证码刷新
$('.img_refresh').click(function () {
$('.valid_img')[0].src += '?'; });
my action
from django.shortcuts import render,redirect,HttpResponse
from django.contrib import auth
from blog01.models import *
from blog01 import models
import random
from io import BytesIO
import json
from blog01 import forms def valid_code(request):
'''create valid code picture'''
f = BytesIO() #实例化BytesIo,创建一个内存存储文件的句柄
img = Image.new(mode='RGB', #图片格式
size=(120,30), #图片大小
color=(random.randint(0,255),random.randint(0,255),random.randint(0,255))) #随机设置图片颜色
draw = ImageDraw.Draw(img,mode="RGB") #创建画笔句柄,讲imag 传入进去 code_list=[] #存储验证码
for i in range(5):
char = random.choice([chr(random.randint(65,90)),str(random.randint(0,9))]) #随机生成字母和数字
code_list.append(char) #添加到存储验证码到列表
font = ImageFont.truetype('blog01/static/bootstrap/fonts/kumo.ttf',28) #设置字体和大小
draw.text([i*24,0],char,(random.randint(0,255),random.randint(0,255),random.randint(0,255)),font=font) #画干扰线
for i in range(5):
x1 = random.randint(0, 120)
y1 = random.randint(0, 120)
x2 = random.randint(0, 120)
y2 = random.randint(0, 120)
draw.line((x1, y1, x2, y2), fill=(random.randint(0, 255),random.randint(10, 255),random.randint(64, 255))) # 画干扰点
for i in range(40):
draw.point([random.randint(0, 120), random.randint(0, 30)], fill=(random.randint(0, 255),random.randint(10, 255),random.randint(64, 255))) # 画干扰圆
for i in range(40):
draw.point([random.randint(0,120), random.randint(0, 30)], fill=(random.randint(0, 255),random.randint(10, 255),random.randint(64, 255)))
x = random.randint(0, 120)
y = random.randint(0, 30)
draw.arc((x, y, x + 4, y + 4), 0, 90, fill=(random.randint(0, 255),random.randint(10, 255),random.randint(64, 255))) img.save(f,'png') #讲绘制好的图片保存到f内存里
data = f.getvalue() #从f里获取存取的二进制文件 validCode = ''.join(code_list) #拼接验证码 request.session['validCode']=validCode #讲验证码存入session里 return HttpResponse(data) #讲二进制文件返回给前端 def register(request):
'''render register html''' form_obj = forms.RegisterForm()
if request.method == "POST":
reponse_data = {}
state = False
error_message = ''
form_obj = forms.RegisterForm(request,request.POST)# if form_obj.is_valid(): #验证form 表单里的数据是否合格
data = form_obj.cleaned_data #clean_data取出jango form表单里的合格数据
data.pop('re_password') #删除非数据库里的字段
data.pop('valid_code')
file_obj = request.FILES.get("avatar")
data['avatar'] = file_obj
UserInfo.objects.create_user(**data) #userinfo继承django user,并创建用户(创建用户存数据时会自动给用户密码加密)
state=True else:
errors = form_obj.errors
error_message = errors
reponse_data['error_message']=error_message
reponse_data['state']=state
return HttpResponse(json.dumps(reponse_data)) #pythons数据类型和js数据类型不一样,记得json序列化一下 return render(request,'register.html',{'form_obj':form_obj})
views.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by Mona on 2017/9/6 from django import forms
from django.core.exceptions import ValidationError
from django.forms.utils import ErrorList
from blog01 import models # ******************************register html*********************************************************
class RegisterForm(forms.Form):
'''create a Form class for register html''' def __init__(self, request=None,*args,**kwargs):
super(RegisterForm,self).__init__(*args,**kwargs)
self.request=request #要往session里加值,必须重写init方法,将request传入 username = forms.CharField(min_length=5, #设置字段最小长度为5
max_length=12,
widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Username'}),
error_messages=({'required':'不能为空'})) #设置默认错误信息 password = forms.CharField(widget=forms.PasswordInput(attrs={'class':'form-control','placeholder':'Password'}),
error_messages={'required':'不能为空'})
re_password = forms.CharField(widget=forms.PasswordInput(attrs={'class':'form-control','placeholder':'Password'}),
error_messages={'required': '不能为空'})
email = forms.EmailField(widget=forms.EmailInput(attrs={'class':'form-control','placeholder':'Email'}),
error_messages={'required': '不能为空','invalid':'格式错误'}) valid_code = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Valid Code'}),
error_messages={'required': '不能为空', 'invalid': '格式错误'}) def clean_password(self):
'''tail a hook for verification 设置局部的钩子对form表单定制验证方法,格式参照源码 '''
if len(self.cleaned_data['password'])>=8: return self.cleaned_data['password']
else:
raise ValidationError('密码长度必须大于8位') def clean_re_password(self):
'''tail a function for verification '''
if len(self.cleaned_data['re_password']) >= 8:
return self.cleaned_data['re_password']
else:
raise ValidationError('密码长度必须大于8位') def clean_username(self):
'''tail a function for username verification'''
if self.cleaned_data['username'].isdigit() or self.cleaned_data['username'].isalpha():
raise ValidationError('用户名必须由数字和字母组成')
else:
if models.UserInfo.objects.filter(username=self.cleaned_data['username']):
raise ValidationError('用户名已占用,请更改用户名')
else:
return self.cleaned_data['username'] def clean_valid_code(self):
'''set global handler for valid code verification'''
if self.cleaned_data.get('valid_code', '').upper() == self.request.session['validCode'].upper():
return self.cleaned_data['valid_code']
else:
raise ValidationError('验证码错误') def clean(self):
'''set global hook for password verification. if first password equal repeat password,
设置全局对钩子,对多个字段同时比较或验证'''
if self.cleaned_data.get("password",0) == self.cleaned_data.get("re_password",1):
return self.cleaned_data
else:
raise ValidationError("密码不一致") # ****************************************************************************************************
form.py
Django---Blog系统开发之注册页面(验证码&ajax发送文件)的更多相关文章
- 基于web的网上书城系统开发-----登录注册扩展-------验证码功能
public class CheckCode extends HttpServlet { private static final long serialVersionUID = 1L; privat ...
- [课程设计]Scrum 3.2 多鱼点餐系统开发进度(页面优化&下单详细信息页面)
Scrum 3.2 多鱼点餐系统开发进度(页面优化&下单详细信息页面) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选 ...
- Scrum 3.2 多鱼点餐系统开发进度(页面优化&下单详细信息页面)
Scrum 3.2 多鱼点餐系统开发进度(页面优化&下单详细信息页面) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选 ...
- Django中数据传输编码格式、ajax发送json数据、ajax发送文件、django序列化组件、ajax结合sweetalert做二次弹窗、批量增加数据
前后端传输数据的编码格式(contentType) 提交post请求的两种方式: form表单 ajax请求 前后端传输数据的编码格式 urlencoded formdata(form表单里的) ja ...
- Django学习笔记(17)——BBS+Blog项目开发(1)验证码功能的实现
本文主要学习验证码功能的实现,为了项目BBS+Blog项目打下基础. 为了防止机器人频繁登陆网站或者破坏分子恶意登陆,很多用户登录和注册系统都提供了图形验证码功能. 验证码(CAPTCHA)是“Com ...
- Django认证系统实现的web页面
结合数据库.ajax.js.Djangoform表单和认证系统的web页面 一:数据模块 扩展了Django中的user表,增加了自定义的字段 from django.db import models ...
- .Net程序猿乐Android开发---(4)注册页面布局
接下来我们介绍的登陆页面布局,在本节中,我们看一下注册页面布局,页面布局大同小异,来一起熟悉下基本控件的使用方法. 效果图: 1.加入注冊页面 右键选中layout目录,加入注冊页面.例如以下图 点击 ...
- [oldboy-django][2深入django]登录注册页面验证码
后台生成随机验证码 #验证码生成 - 在login.html 中有一张验证码图片 设置图片的src url, 相当于发送一次get请求,返回的内容为图片渲染的内容 <div class=&quo ...
- Code笔记 之:注册页面验证码
文章内容包括: 1.验证码制作 -- 中文|字母|数字|…… 2.图文验证码 -- 图片防盗链(PHP而非JS) 3.JS防止右键点击图片 4.input表单输入框不记录输入过的信息 5.CSS+di ...
随机推荐
- 使用.NET JustDecompile来反编译你的程序代码
前言 在项目的进行中有时会碰到需要去了解由第三方所开发的程序代码或者因为年久已经遗失原始码的程序,由于因为是别人写的所以我们并没有原始码可以直接阅读,碰到这种情况我们就需要去反编译这些程序及 DLL ...
- Web services 有两种类型的应用
可重复使用的应用程序组件 有一些功能是不同的应用程序常常会用到的.那么为什么要周而复始地开发它们呢? Web services 可以把应用程序组件作为服务来提供,比如汇率转换.天气预报或者甚至是语言翻 ...
- Eclipse 运行程序
运行 Java 程序 我们可以在 Package Explorer 视图 可以在 Package Explorer 视图中快速运行 Java 程序. Package Explorer 视图: 鼠标右击 ...
- ExtJs学习-搭建开发环境
Extjs是一个非常棒的ajax框架,可以用来开发十分绚丽外观的客户端框架,能使B/S框架更加具有活力.它是一个用javascript编写的框架,与后台技术无关的ajax框架.因此,可以把ExtJs使 ...
- 猜数字游戏-python
题目: 用python写一个猜数字的游戏,游戏规则如下: 1.由一个人随机写一个整数1-99(如:21) 2.一群小伙伴轮流猜数字,如第一个人猜一个数(如:48),则缩小范围至(1-48) 3.如第二 ...
- ios - UILabel_长按复制
1.添加长按的手势 UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWith ...
- mysql小知识点汇总
附录:(更新于2013-11-21) sql必知必会学习笔记:http://www.cnblogs.com/IPrograming/category/509859.html mysql 基本命令学习: ...
- 160817、Java数据类型以及变量的定义
Java 是一种强类型的语言,声明变量时必须指明数据类型.变量(variable)的值占据一定的内存空间.不同类型的变量占据不同的大小. Java中共有8种基本数据类型,包括4 种整型.2 种浮点型. ...
- jPage.js分页
jPage.js插件使用文档 这一款插件主要是为了bootstrap原生的分页功能效果不理想而诞生的一款插件. jPage.js代码更新地址为:https://github.com/leslieSie ...
- mock数据(模拟后台数据)
mock数据(模拟后台数据) - Emily恩 - 博客园 https://www.cnblogs.com/enboke/p/vue.html Mock.js http://mockjs.com/ 前 ...