基于forms组件和Ajax实现注册功能

1 基于forms组件设计注册页面

  --点击头像 === 点击input

  --头像预览:

    修改用户选中的文件对象;获取文件对象的路径;修改img的src属性,src=文件对象路径。

forms组件不仅可以校验字段值,还可以渲染标签(3种方法)

login.html

<a href="/register/" class="btn btn-success pull-right">注册</a>

1.基于forms组件的注册页面设计

修改  获取用户选中的文件对象;获取文件对象的路径;修改img标签的src属性,让src=文件对象路径。

register.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/blog/bootstrap/css/bootstrap.css">
{# <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css">#}
<style type="text/css">
#avatar_img{ //给它加一个css样式
margin-left: 20px;
}
#avatar{
display: none; //设置让它隐藏起来,写到css里边
}
</style>
<script>
window.onload= function () { //window.onload事件--->>>
$("#id_user").val("hello"); //下面所有的标签都执行加载完之后,你再给我加载这句话。它执行到这一步的时候只是把这个事件绑定下并不会执行里边的代码
}
</script> </head>
<body>
<h3>注册页面</h3>
<div class="container">
<div class="row">
<div class="col-md-6 col-lg-offset-3">
<form>
{% csrf_token %}
{% for field in form %} {# for 循环这个form,也就是user、pwd、re_pwd、email这些字段,进行渲染#}
<div class="form-group">
//<label for="user">{{ field.label }}</label> //label里边for的值和input标签id的值一样,点击label就相当于点击input标签
              <label for="{{field.auto_id}}"> {{field.label}} </label> #不要写死了,渲染出:for = "id_user"与下面input标签的id=“id_user”一样
{{ field }} {#这个它渲染出来有input标签,会跟字段的名字一致,只不过在这里要发ajax;给它加一个"class":"form-control"页面就变好看了#}
</div>
{% endfor %}
#########################################注册页面的头像预览,默认头像
<div class="form-group"> {#把头像没有放到input里边,把它单独处理了,它不需要校验#}
<label for="avatar">
头像 // 点击头像就相当于点击input标签 //把这个img标签放到label标签里边
<img id="avatar_img" width="60" height="60" src="/static/blog/img/default.png" alt=""> //点击img标签就相当于点击input
</label>
<input type="file" id="avatar" > //这时候这个标签就没有意义了,把它隐藏起来就可以了。style=“display:none"
</div>
<input type="button" class="btn btn-default reg_btn" value="submit"><span class="error"></span>
<a href="/register/" class="btn btn-success pull-right">注册</a>
</form>
</div>
</div>
</div> <script src="/static/js/jquery-3.2.1.min.js"></script> <script>
//头像预览
</script> </body>
</html>

Myforms.py

from django import forms
from django.forms import widgets from blog.models import UserInfo
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError class UserForm(forms.Form):
user=forms.CharField(max_length=32,
error_messages={"required": "该字段不能为空"},
label="用户名", widget=widgets.TextInput(attrs={"class":"form-control"},)) #label标签,这样子它就渲染出中文了
pwd = forms.CharField(max_length=32,label="密码", widget=widgets.PasswordInput(attrs={"class":"form-control"},))
re_pwd = forms.CharField(max_length=32,label="确认密码", widget=widgets.PasswordInput(attrs={"class":"form-control"},))
email = forms.EmailField(max_length=32,label="邮箱", widget=widgets.EmailInput(attrs={"class":"form-control"},))

2.注册页面的默认头像

把img标签写到label里边去,点击头像就相当于点击input标签

http://127.0.0.1:8000/static/blog/img/default.png,这样子就可以访问到这个默认的注册头像

很多网站是这样子:把input标签的长宽跟这个头像一致,然后利用css里边定位position=absolute,把这两个标签定位到一个位置上去。再把input标签透明度显示为0,这时候它俩叠到一起了,你点击头像也就点击了input标签。   另外一种思路是:利用label标签的for的值与input标签的id值一致就可以了,点击label相当于点击input标签。

3.注册页面的头像预览功能

Console--->>

$("#avatar")
r.fn.init [input#avatar]0: input#avatarlength: 1__proto__: Object(0)
$("#avatar")[0]
<input type=​"file" id=​"avatar">​
$("#avatar")[0].files
FileList {0: File(593239), length: 1}0: File(593239) {name: "distance.png", lastModified: 1510650980163, lastModifiedDate: Tue Nov 14 2017 17:16:20 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 593239, …}length: 1__proto__: FileList
$("#avatar")[0].files[0]
File(593239) {name: "distance.png", lastModified: 1510650980163, lastModifiedDate: Tue Nov 14 2017 17:16:20 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 593239, …}

头像预览:

    修改用户选中的文件对象;获取文件对象的路径;修改img的src属性,src=文件对象路径。

<script>
//头像预览
$("#avatar").change(function () { //change事件,选中文本之后事件就发生了
//获取用户选中的文件对象 $(this)就是这个input标签
var file_obj = $(this)[0].files[0];
//获取文件对象的路径
var reader = new FileReader(); //基于一个文件阅读器,类实例化
reader.readAsDataURL(file_obj); //只要文件的路径,把文件传进去; FileReaderURL是读取文件的URL,读完之后把会它结果放在reader内置的对象里边,没有返回值
//修改img的src属性 , src=文件对象的路径
reader.onload= function () { //等加载完之后才执行里边的代码,这样子就可以预览了。onload事件
$("#avatar_img").attr("src",reader.result) //结果在reader.result里边
};
});
</script>

4.基于Ajax提交formdata数据

点击提交(什么都不输入直接submit)的错误信息在这里边:---->>> { user:null,msg:{ } }

//基于Ajax提交数据
$(".reg_btn").click(function () {
console.log($("#form").serializeArray()); //找到form这个标签,打印下,它会对这里边的所有有效控件进行整理。见下面截图,(5)[{..}, {..}, {..}, {..}, {..} ]
var formdata = new FormData(); //对下面注释内容的优化版本
var request_data = $("#form").serializeArray();
$.each(request_data, function (index, data) { //循环这个request_data,键是index, 值是form的有效控件data
formdata.append(data.name,data.value) //每循环一次append一次
});
formdata.append("avatar", $("#avatar")[].files[]); //最后再把这个avatar文件单独加下 {# var formdata = new FormData(); //Ajax上传文件一定要换成FormData的格式,构建一个对象传到这里边#}
{# formdata.append("user",$("#id_user").val()); //传过去的键和值#}
{# formdata.append("pwd",$("#id_pwd").val());#}
{# formdata.append("re_pwd",$("#id_re_pwd").val());#}
{# formdata.append("email", $("#id_email").val());#}
{# formdata.append("avatar", $("#avatar")[].files[]);#}
{# formdata.append("csrfmiddlewaretoken", $("[name = 'csrfmiddlewaretoken']").val());#}
$.ajax({
url:"",
type:"post",
contentType:false, //要加两个参数不然会报错;数据的编码类型
processData:false, //只要是formdata都要加这两个参数
data: formdata, //把上边formdata构建出来之后,加到这里边来
success: function (data) {
console.log(data);
##########################################5.基于Ajax在注册页面显示错误信息。#############
if(data.user){
//注册成功,跳转登录页面
location.href = "/login/"
}
else{//注册失败
//console.log(data.msg) 把错误信息msg取出来
$("span.error").html(""); //清空错误信息
$(".form-group").removeClass("has-error"); //把边框的颜色去掉
//展示此次提交的错误信息
$.each(data.msg, function(field, error_list){ //依次循环msg这个object,function里边是循环的键值,键是每个错误字段的字符串,值是错误信息的列表。
console.log(field, error_list); //赋值, //field错误字段叫的名字 和input标签的id值是有关联的 if (field == "__all__"){ //处理全局错误信息;下面找到它的标签,父标签给它加上
$("#id_re_pwd").next().html(error_list[]).parent().addClass("has-error");
} $("#id_"+field).next().html(error_list[0]); //每次循环都把各自的错误信息放到input标签的span标签里面。.next()是找它的下一个标签即span标签
$("#id_"+field).parent().addClass("has-error"); //变颜色
}) }
}
})
})

views.py

def register(request):
if request.is_ajax(): #你点击那个按钮既是Ajax请求又是post请求。既可以用Ajax也可用method=post作分支判断
print(request.POST) #把所有提交的数据都取出来
form = UserForm(request.POST) #用UserForm做检验,
response = {"user":None, "msg":None} #发Ajax一般都会返回一个字典来进行标示这些行为
if form.is_valid(): #数据全通过,成功
response["user"] = form.cleaned_data.get("user") #成功了让它等于 = 注册人的名字
else: #失败了-->>
print(form.cleaned_data) #干净数据都在这里边
print(form.errors) #错误数据都在这里边
response["msg"] = form.errors #失败了之后把这所有的错误信息放到msg里边
return JsonResponse(response)
form = UserForm()
return render(request,"register.html", {"form":form})

5. 基于Ajax在注册页面显示错误信息

    <style type="text/css">
.error{
color:red; //给错误信息加的css样式
}
</style>

代码见上

id_user的父标签是form-group--->>给它加一个叫addClass的方法,相当于这个标签多了个叫has-error的名字

6.forms组件的局部钩子与全局钩子的应用

Myforms.py

  from blog.models import UserInfo
  from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
def clean_user(self):
val=self.cleaned_data.get("user")
user = UserInfo.objects.filter(username=val).filter()
if not user:
return val
else:
raise ValidationError("该用户已注册") def clean(self): #全局钩子
pwd = self.cleaned_data.get("pwd")
re_pwd = self.cleaned_data.get("re_pwd")
if pwd and re_pwd:
if pwd == re_pwd:
return self.cleaned_data
else:
raise ValidationError("两次密码不一致") #全局错误
else:
return self.cleaned_data

views.py

from blog.Myforms import UserForm  #引入即可

全局错误可以在视图里边取出来,跟之前form表单提交错误信息不一样,之前是把错误信息放到视图里边,放到模板里边去。这里可以直接在register里边

错误信息在errors里边,里边有个键叫__all__,对应列表error_list的信息,发给ajax了,ajax拿到数据做下判断---->>>

 if (field == "__all__"){   //处理全局错误信息;下面找到它的标签,父标签给它加上
$("#id_re_pwd").next().html(error_list[0]).parent().addClass("has-error"); //给它放到re_pwd确认密码的下面
}

2.1博客系统 |基于form组件和Ajax实现注册登录的更多相关文章

  1. 3- 功能2:基于forms组件和ajax实现注册功能

    1.forms组件的注册页面 url from django.urls import path, re_path from blog import views from django.views.st ...

  2. 基于forms组件和Ajax实现注册功能

    一.基于forms组件的注册页面设计 1.运用forms组件的校验字段功能实现用户注册 views.py:    (在钩子中代码解耦,将form放在cnblog/blog/Myforms.py中) f ...

  3. web开发-Django博客系统

    项目界面图片预览 项目代码github地址 项目完整流程 项目流程: 1 搞清楚需求(产品经理) (1) 基于用户认证组件和Ajax实现登录验证(图片验证码) (2) 基于forms组件和Ajax实现 ...

  4. 2.2博客系统 |FileField字段 |Media配置

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

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

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

  6. 欢迎阅读daxnet的新博客:一个基于Microsoft Azure、ASP.NET Core和Docker的博客系统

    2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客.当然,我写博客也不是从2008年才开始的,在更早时候,也在CSDN和系统分析员协会(之后名为"希赛网" ...

  7. 一个基于Microsoft Azure、ASP.NET Core和Docker的博客系统

    2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客.当然,我写博客也不是从2008年才开始的,在更早时候,也在CSDN和系统分析员协会(之后名为“希赛网”)个人空间发布过一些 ...

  8. 【ASP.NET实战教程】基于ASP.NET技术下多用户博客系统全程实战开发(NNblog)

    岁末主推:牛牛老师主讲,多用户博客系统,基于ASP.NET技术,年后将带来移动业务平台项目项目目标: 打造个性品牌Blogo,定制多用户博客 为每一个博客用户提供个性化的 blogo解决方案,打造精品 ...

  9. 基于Microsoft Azure、ASP.NET Core和Docker的博客系统

    欢迎阅读daxnet的新博客:一个基于Microsoft Azure.ASP.NET Core和Docker的博客系统   2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客 ...

随机推荐

  1. linux系统--磁盘管理命令(一)

    一.基本命令 1.1 查看磁盘分区使用状况:df 参数: l:仅显示本地磁盘(默认) a:显示所有文件系统的磁盘使用情况,包括比如 /proc/ h:以1024进制计算最合适的单位显示磁盘容量 H:以 ...

  2. JS——取消事件冒泡,实现div的显示与隐藏 event.cancelBubble = true;

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. pyqt5 添加属性-类方法用属性形式访问

    方法一 装饰器法 import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout,QLab ...

  4. C# 反编译项目修复

    1.反编译测试程序 1>.将测试程序添加到.NET Reflector 2>.选中测试程序后右键选择导出 2.反编译项目修复 1>.问题一 问题现象: base.AutoScaleM ...

  5. XML解析技术简介——(一)

  6. shiroWeb项目-授权(十一)

    使用PermissionsAuthorizationFilter 在applicationContext-shiro.xml中配置url所对应的权限. 测试流程: 1.在applicationCont ...

  7. Django开发笔记六

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.登录功能完善 登录成功应该是重定向到首页,而不是转发 ...

  8. 【windows核心编程】远程线程DLL注入

    15.1 DLL注入 目前公开的DLL注入技巧共有以下几种: 1.注入表注入 2.ComRes注入 3.APC注入 4.消息钩子注入 5.远线程注入 6.依赖可信进程注入 7.劫持进程创建注入 8.输 ...

  9. MySQL— 基础

    目录 一.MySQL概述 二.下载安装 三.数据库操作 四.数据表操作 五.表内容操作 一.MySQL概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracl ...

  10. 【转】通过xml处理sql语句时对小于号与大于号的处理转换

    当我们需要通过xml格式处理sql语句时,经常会用到< ,<=,>,>=等符号,但是很容易引起xml格式的错误,这样会导致后台将xml字符串转换为xml文档时报错,从而导致程序 ...