Django 博客项目02 Form验证+ 上传头像(预览)+Ajax用户注册
头像预览
$("#avatar_file").change(function(){
// 获取上传的文件对象
var file=$(this)[0].files[0];
// 读取文件的URL
// 创建阅读器
var reader=new FileReader();
// 读取file的URL
reader.readAsDataURL(file);
// 监听读取,onload在读完之后触发事件(是给DOM对象绑定事件)
reader.onload=function() {
// this.result 是刚刚读取的结果
$("#avatar_img").attr("src",this.result)
}
});
头像预览
头像重叠于文件上传
css:
/*头像与文件上传叠在一起,参照物是.avatar_box,已定位的父亲*/
#avatar_img{
width: 60px;
height: 60px;
left:;
top:;
}
#avatar_file{
width: 60px;
height: 60px;
position: absolute;
left:;
top:;
opacity:;
}
.avatar_box{
position: relative;
}
头像与文件上传叠在一起
ajax注册+Form验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css">
<script src="/static/js/jquery-3.2.1.min.js"></script>
<link rel="stylesheet" href="/static/css/register.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<form class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<label for="id_user" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-10">
{{ regForm.user }} <span class="pull-right"></span>
</div>
</div>
<div class="form-group">
<label for="id_pwd" class="col-sm-2 control-label">密码</label>
<div class="col-sm-10">
{{ regForm.pwd }}<span class="pull-right"></span>
</div>
</div>
<div class="form-group">
<label for="id_repeat_pwd" class="col-sm-2 control-label">确认密码</label>
<div class="col-sm-10">
{{ regForm.repeat_pwd }}<span class="pull-right"></span>
</div>
</div>
<div class="form-group">
<label for="id_email" class="col-sm-2 control-label">邮箱</label>
<div class="col-sm-10">
{{ regForm.email }}<span class="pull-right"></span>
</div>
</div>
<div class="form-group">
<label for="avatar_file" class="col-sm-2 control-label">头像</label>
<div class="col-sm-10">
<div class="avatar_box ">
<img src="/static/img/default.png" alt="" id="avatar_img">
<input type="file" class="form-control" id="avatar_file">
</div>
</div>
</div>
<div class="form-group">
<label for="id_valid_code" class="col-sm-2 control-label">验证码</label>
<div class="col-sm-5">
{{ regForm.valid_code }}<span class="pull-right"></span>
</div>
<div class="col-sm-5">
<img style="margin-left: -17px" src="/get_valid_img/" alt="" width="230" height="33"
id="valid_img">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="button" value="注册" class=" btn-primary form-control regBtn ">
</div>
</div>
<div class="col-sm-offset-2 col-sm-10">
<div class="form-group" style="margin-left:-10px">已有账号?<a href="/login/">立即登录</a></div>
</div>
</form>
</div>
</div>
</div>
<script>
// 刷新验证码
$("#valid_img").click(function () {
$(this)[0].src += "?"
});
// 头像预览
$("#avatar_file").change(function () {
// 获取上传文件对象
var file = $(this)[0].files[0];
// 读取文件URL
var reader = new FileReader();
reader.readAsDataURL(file);
// 阅读文件完成后触发的事件
reader.onload = function () {
$("#avatar_img").attr("src", this.result); // 读取的URL结果:this.result
}
});
// 提交注册数据
$(".regBtn").click(function () {
var $formData = new FormData();
$formData.append("user", $("#id_user").val());
$formData.append("pwd", $("#id_pwd").val());
$formData.append("repeat_pwd", $("#id_repeat_pwd").val());
$formData.append("email", $("#id_email").val());
$formData.append("valid_code", $("#id_valid_code").val());
var file = $("#avatar_file")[0].files[0];
$formData.append("file_img", file);
$formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
$.ajax({
url: "/register/",
type: "POST",
data: $formData,
processData: false,
contentType: false,
success: function (data) {
if (data.user) {
location.href = "/login/"
}
else {
$("span").html("");
$(".form-group").removeClass("has-error");
console.log(data.errors); // {"user":["",""],"pwd":["",""]}
$.each(data.errors, function (i, j) { // i : 错误字段名称 j: 该字段所有错误列表
$("#id_" + i).next().addClass("pull-right").css("color", "red").html(j[0]).parent().parent().addClass("has-error");
// __all__校验的是全局钩子
if (i == "__all__") {
$("#id_repeat_pwd").next().addClass("pull-right").css("color", "red").html(j[0]).parent().parent().addClass("has-error");
}
})
}
}
})
})
</script>
</body>
</html>
register.html
/*距顶端50px*/
.container {
margin-top:100px;
}
body {
background-color: #eeeeee;
}
/*头像与文件上传叠在一起,参照物是.avatar_box,已定位的父亲*/
#avatar_img {
width: 60px;
height: 60px;
left:;
top:;
}
#avatar_file {
width: 60px;
height: 60px;
position: absolute;
left:;
top:;
opacity:;
}
.avatar_box {
position: relative;
}
register.css
from django import forms
from django.forms import widgets
from .models import UserInfo
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class RegForm(forms.Form):
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request
user = forms.CharField(min_length=5, max_length=12,
error_messages={"min_length": "最小长度为5"},
widget=widgets.TextInput(attrs={"class": "form-control", "placeholder": "Username"})
)
pwd = forms.CharField(
widget=widgets.PasswordInput(attrs={"class": "form-control", "placeholder": "Password"})
)
repeat_pwd = forms.CharField(
widget=widgets.PasswordInput(attrs={"class": "form-control", "placeholder": "Confirm Password"})
)
email = forms.EmailField(error_messages={"invalid": "格式错误!"},
widget=widgets.EmailInput(attrs={"class": "form-control", "placeholder": "Email"})
)
valid_code = forms.CharField(
widget=widgets.TextInput(attrs={"class": "form-control", "placeholder": "Validcode"})
)
def clean_user(self):
user = UserInfo.objects.filter(username=self.cleaned_data.get("user"))
if not user:
return self.cleaned_data.get("user")
else:
raise ValidationError("用户名已经存在!")
def clean_pwd(self):
pwd = self.cleaned_data.get("pwd")
if pwd.isdigit() or pwd.isalpha():
raise ValidationError("不能是纯数字或者纯字母")
else:
return pwd
def clean_valid_code(self):
val = self.cleaned_data.get("valid_code") # 用户输入的验证码
if val.upper() == self.request.session.get("valid_code_str").upper():
return self.cleaned_data.get("valid_code")
else:
raise ValidationError("valid code error!")
def clean(self):
if self.cleaned_data.get("pwd"):
if self.cleaned_data.get("pwd") == self.cleaned_data.get("repeat_pwd"):
return self.cleaned_data
else:
raise ValidationError("两次密码不一致!") # key 是__all__
forms.py
from django.shortcuts import render, redirect, HttpResponse
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
from PIL import Image
from django.contrib import auth
from django.http import JsonResponse
from .models import *
def get_valid_img(request):
def get_random_color():
# 生成随机色
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
def get_random_char():
# 生成随机字符
random_num = str(random.randint(0, 9)) # 随机数字
random_upper_alph = chr(random.randint(65, 90)) # 随机大写字母
random_lowwer_alph = chr(random.randint(79, 122)) # 随机小写字母
random_char = random.choice([random_num, random_lowwer_alph, random_upper_alph])
return random_char # 返回随机字符
# 生成画布图片
image = Image.new(mode="RGB", size=(230, 33), color=get_random_color())
# 生成画笔
draw = ImageDraw.Draw(image, mode="RGB")
# 指定字体
font = ImageFont.truetype("blog/static/font/kumo.ttf", 32)
valid_code_str = "" # 用来拼接验证码
# 写入6个随机字符(数字,字母)
for i in range(1, 6):
char = get_random_char()
valid_code_str += char # 拼接验证码
draw.text([i * 40, 5], char, get_random_color(), font=font)
width = 230
height = 33
# 生成80个点
for i in range(80):
draw.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color())
# 生成两根干扰线
for i in range(2):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
draw.line((x1, y1, x2, y2), fill=get_random_color())
# 暂存内存
f = BytesIO()
image.save(f, "png")
# 从内存中取
data = f.getvalue()
# 将验证码保存在session
request.session["valid_code_str"] = valid_code_str
return HttpResponse(data)
def log_in(request):
if request.is_ajax():
user = request.POST.get('username')
pwd = request.POST.get('pwd')
valid_code = request.POST.get('valid_code')
# 获取session里面的验证码
valid_code_str = request.session.get("valid_code_str")
# 也可以这样写:valid_code_str=request.session["valid_code_str"]
loginResponse = {"user": None, "error_msg": ''}
# 先对验证码进行校验(不区分大小写)
if valid_code_str.upper() == valid_code.upper():
# 验证码通过,再对用户名密码进行校验(要导入auth)
user = auth.authenticate(username=user, password=pwd)
if user:
auth.login(request, user) # 设置session
loginResponse["user"] = user.username
else:
loginResponse["error_msg"] = "username or password is wrong!"
else:
# 验证码不通过,不再进行下面的验证,直接返回提示错误信息
loginResponse["error_msg"] = " valid code is wrong!"
# JsonResponse可完成json数据的转换工作,简便!
return JsonResponse(loginResponse)
return render(request, 'login.html')
def index(request):
return render(request, 'index.html')
from blog.forms import *
from .forms import *
def register(request):
# ajax请求:
if request.is_ajax():
regForm = RegForm(request, request.POST)
regResponse = {"user": None, "errors": None}
if regForm.is_valid():
# 注册
data = regForm.cleaned_data
user = data.get("user")
pwd = data.get("pwd")
email = data.get("email")
avatar_img = request.FILES.get("file_img")
user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email, avatar=avatar_img)
regResponse["user"] = user
else:
regResponse["errors"] = regForm.errors
return JsonResponse(regResponse)
# get请求:
regForm = RegForm(request)
return render(request, "register.html", {"regForm": regForm})
views.py
from django.conf.urls import url
from django.contrib import admin
from blog import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 登录
url(r'^login/', views.log_in),
# 验证码
url(r'^get_valid_img/', views.get_valid_img),
# 注册
url(r'^register/', views.register),
# 主页
url(r'^$', views.index),
url(r'^index/', views.index),
]
urls.py
效果图:

错误提示:

Django 博客项目02 Form验证+ 上传头像(预览)+Ajax用户注册的更多相关文章
- Jcrop+uploadify+php实现上传头像预览裁剪
最近由于项目需要,所以做了一个上传头像预览并且可以预览裁剪的功能,大概思路是上传的图片先保存到服务器,然后通过ajax从服务器获取到图片信息,再利用Jcrop插件进行裁剪,之后通过PHP获取到的四个裁 ...
- form表单系列中文件上传及预览
文件上传及预览 Form提交 Ajax 上传文件 时机: 如果发送的[文件]:->iframe, jQurey(),伪Ajax 预览 import os img_path = os.path.j ...
- js实现图片上传及预览---------------------->>兼容ie6-8 火狐以及谷歌
<head runat="server"> <title>图片上传及预览(兼容ie6/7/8 firefox/chrome)</title> & ...
- hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images
hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images, 本例子主要是使用HTML5 的File API,建立一個可存取到该file的url, 一个空的img标签,ID为img0,把 ...
- 【转】HTML5 jQuery图片上传前预览
hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images,本例子主要是使用HTML5 的File API,建立一個可存取到该 file的url,一个空的img标签,ID为img0,把选 ...
- HTML5 jQuery图片上传前预览
hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images,本例子主要是使用HTML5 的File API,建立一個可存取到该file的url,一个空的img标签,ID为img0,把选择 ...
- vue开发中vue-resource + canvas 图片压缩、上传、预览
1.使用vue-resource上传,也可以自定义ajax上传: 2.使用<input type="file" @change="submit()" na ...
- JQuery插件:图片上传本地预览插件,改进案例一则。
/* *名称:图片上传本地预览插件 v1.1 *作者:周祥 *时间:2013年11月26日 *介绍:基于JQUERY扩展,图片上传预览插件 目前兼容浏览器(IE 谷歌 火狐) 不支持safari *插 ...
- JS兼容各个浏览器的本地图片上传即时预览效果
JS兼容各个浏览器的本地图片上传即时预览效果 很早以前 在工作曾经碰到这么一个需求,当时也是纠结了很久,也是google了很久,没有碰到合适的demo,今天特意研究了下这方面的的问题,所以也就做了个简 ...
随机推荐
- spring boot 学习(二)spring boot 框架整合 thymeleaf
spring boot 框架整合 thymeleaf spring boot 的官方文档中建议开发者使用模板引擎,避免使用 JSP.因为若一定要使用 JSP 将无法使用. 注意:本文主要参考学习了大神 ...
- gitlab永久设置密码
在 .gitconfig 文件中加入: [credential] helper = store .git-credentials close address
- Xshell5 Xftp安装图解
1Xshell5 Xftp_5安装图解 2.1Xshell5安装 2.2Xftp安装
- OPENVZ低版本centos6.5安装BBR加速手记
玩 VPS,开机第一件事就是安装 BBR,至于效果怎么样还真不好说,依据不同的线路质量而定,但有总比没有好. 因为这次用的是 openvz 平台,所以找了一个网上的 ovz 专用的 BBR 一键安装代 ...
- 需求改进&系统设计
1.需求&原型改进 针对课堂讨论环节老师和其他组的问题及建议,对修改选题及需求进行修改,发现在原有需求下,无需进行过大修改. 2.系统设计 3.Alpha任务分配计划 待定 4.测试计划 测试 ...
- DevExpress v17.2新版亮点——CodeRush篇(一)
用户界面套包DevExpress v17.2日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了CodeRush v17.2 的新功能,快来下载试用新版本! Unit Test ...
- 想ACCESS数据库插入新的用户
public string AddUserN = ""; //定义用户名字符串 public string paswrd1 = ""; //密码1 public ...
- Linux 之 tar和nc传文件
前提: 将 172.16.88.1 上的 test 文件夹传送到 172.16.88.2 上 接收方 ---- 172.16.88.2 $ nc -l > test.tar 9876 为端口号 ...
- 如何使用firebug
什么是Firebug 从事了数年的Web开发工作,越来越觉得现在对WEB开发有了更高的要求.要写出漂亮的HTML代码:要编写精致的CSS样式表展示每个页面模块:要调试javascript给页面增加一些 ...
- Robot Framework 自定义库
进入 python安装路径\Lib\site-packages 创建文件夹,库名 创建py文件,myclass.py 创建py文件,__init__.py 导入自定义库 遇到的问题: python版 ...