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

时间:2022-09-12 17:52:25

基于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标签

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

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

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

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

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:{ } }

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

//基于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的名字

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

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

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  #引入即可

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

全局错误可以在视图里边取出来,跟之前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&period;2博客系统 &vert;FileField字段 &vert;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&period;NET Core和Docker的博客系统

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

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

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

  8. 【ASP&period;NET实战教程】基于ASP&period;NET技术下多用户博客系统全程实战开发&lpar;NNblog&rpar;

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

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

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

随机推荐

  1. win10&lowbar;x64更新错误解决&colon; 安装一些更新时出现问题,但我们稍后会重试。如果持续出现这些问题,并且你想要搜索Web或联系支持人员以获取相关信息,以下信息可能会对你有帮助:

    可能的原因: 1.windows 服务没打开 win+r,打开[运行]对话框 输入 [service.msc] 找到 [Windows Firewall]和[Internet connection s ...

  2. 启动管理软件服务器时,提示midas&period;dll错误

    首先确认系统以及管理软件目录内是否有midas.dll文件,如果没有,请复制或下载midas.dll到相应目录.系统默认路径为:'c:\windows\system32\' 然后依次打开“开始菜单”内 ...

  3. 函数防抖 &amp&semi; 函数节流

    避免一个函数频繁执行 - 避免程序卡顿 js 是单线程的,setTimeout 这样的函数是异步的 异步的代码,交给对应的模块进行处理 模块在会将异步任务,在主线程执行完所有同步代码后,加入事件队列 ...

  4. OAuth2&period;0深入理解

    1. OAuth2.0深入理解 1.1. 概念 OAuth(Open Authorization)开放授权,表示将系统功能部分授权给第三方系统调用,实现更细颗粒度的权限控制 OAuth是一种在线授权或 ...

  5. VMPlayer Ubuntu 16&period;04 Copy and Paste with Host 主机与宿机之间的复制粘贴

    使用Ubuntu的虚拟机时如果不能主机之间进行复制粘粘,会非常非常的不方便,所以我们需要安装vmware tools,使用如下的代码(注意第二句一定要有,不然还是不能复制粘贴): sudo apt-g ...

  6. python魔法方法-属性访问控制

    属性访问控制 所谓的属性访问控制就是控制点号访问属性的行为,而且不仅是类的外部,连类的内部也受控制,代码见真章,边看代码边解释: __getattr__(self, item) 定义当访问不存在的属性 ...

  7. Vue学习【第二篇】:ES6简单介绍

    ECMAScript 6简介 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了.它的目标,是使得 JavaScript ...

  8. PostgreSQL增强版命令行客户端(pgcli)

    效果: 安装: https://www.pgcli.com/install 官网: https://www.pgcli.com/

  9. VS 生成 dll、exe 版本号与SVN版本号一致

    1.VS 可自动生成版本号 注释掉以下两行代码 [assembly: AssemblyVersion("1.0.0.0")][assembly: AssemblyFileVersi ...

  10. iOS学习笔记02-UIScrollView

    父类UIView方法 // autoresizingMask - 现在基本弃用,改用autoLayout typedef NS_OPTIONS(NSUInteger, UIViewAutoresizi ...