一、注册相关的知识点

1、Form组件

我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放

2、局部钩子函数

 def clean_username(self):
username = self.cleaned_data.get("username")
valid = models.UserInfo.objects.filter(username = username).first()
if valid:
raise ValidationError("用户名已存在")
return username

3、全局钩子函数

#自定义全局钩子:验证两次密码是否一致
def clean(self):
if self.cleaned_data.get("password") == self.cleaned_data.get("password_again"):
return self.cleaned_data
else:
raise ValidationError("两次密码不一致")

4、 jQuery的属性操作相关的

attr:
一个参数是获取属性的值,两个参数是设置属性值
removeAttr(属性名):
删除属性值
prop:
适应于属性的返回值是布尔类型的(单选,反选,取消的例子)
removePorp:
删除属性的值

5、循环的两种方式:

$.each(数组/对象,function(i,v){})
$("div").each(function(i,v){})

6、css中的三种隐藏:

1、display:none  隐藏所有内容
2、visibility:hidden 隐藏内容
3、overflow:hidden 隐藏溢出内容
三者都是用来隐藏的:
区别在于:
visibility虽然隐藏了,但是被隐藏的内容依然占据这空间,这段隐藏了的内容却保留空间的位置会在网页中显示空白
而display:隐藏了不占用空间
我们在注册的时候不用display:none,不然选择文件的那个功能就没有了,我们可以吧透明度

7、提交二进制数据用FormData

var formData=new FormData();
formData.append("username",$("#id_username").val());
formData.append("email",$("#id_email").val());
formData.append("tel",$("#id_tel").val());
formData.append("password",$("#id_password").val());
formData.append("password_again",$("#id_password_again").val());
formData.append("avatar_img",$("#avatar")[0].files[0]);

记得要加上

contentType:false
processData:false

8、可以用下面的方法判断是什么请求

if request.ajax():    #如果ajax请求
if request,method=="POST": #如果是POST请求

9、上传文件有一个固定的配置参数media,和static相似 但又不同

步骤如下:

- 首先在settings中配置:

# ============media配置===============
MEDIA_URL="/media/" #别名
MEDIA_ROOT=os.path.join(BASE_DIR,"app01","media","uploads") #具体路径

- 在url中配置

url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),

用处:

用处一:
----- avatar = models.FileField(verbose_name='头像', upload_to='avatar', default="/avatar/default.png")
会把接收的文件放在media指代的路径与upload_to的拼接:BASE_DIR+blog+media+uploads+avatar/a.png
avatar字段在数据库中保存的是:avatar/a.png

用处二:

------ <img src="/media/avatar/a.png">

如果上传成功会把图片自动保存在这里

10、头像图片预览

   //头像预览
$(".avatar_file").change(function () {
var ele_file = $(this)[0].files[0]; //当前选中的文件
var reader = new FileReader();
reader.readAsDataURL(ele_file); //对应找到打开的url
reader.onload=function () {
{# 方式一#}
$(".avatar_img").attr("src",this.result) ; //this.result是上面找到的url
{# 方式二#}
{# $(".avatar_img")[0].src=this.result; //设置图片属性#}
}
})

11、form自动生成的错误信息

当你定义了全局钩子的时候,而且正好出现你的那个全局钩子函数中的错(比如两次密码输入不一致),这样你打印错误信息的时候

会有一个__all__对象,这个就是你设置的全局钩子生成的。

所以还要单独判断一下,现在全局钩子只有一个,你可以这样判断,但是,当全局钩子多的时候就得一个一个分开来判断

  if (i=="__all__"){
$("#id_password_again").after($span)
}

二、具体实现注册操作

urls.py

 from django.conf.urls import url
from django.contrib import admin
from app01 import views
from django.conf import settings
from django.views.static import serve
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/$', views.login),
url(r'^index/$', views.index),
url(r'^get_vaildCode_img/$', views.get_vaildCode_img),
url(r'^log_out/$', views.log_out), url(r'^register/$', views.register),
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]

urls.py

views.py

 def register(request):
if request.method=="GET":
form = RegisterForm()
return render(request,"register.html",{"form":form})
else:
form = RegisterForm(data=request.POST)
regresponse = {"user":None,"msg_errors":None}
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
tel = form.cleaned_data.get("tel")
avatar_img = request.FILES.get("avatar_img")
print(">>>",username,password,tel)
models.UserInfo.objects.create_user(username = username,password=password,tel=tel,avatar=avatar_img)
regresponse["user"] = username
else:
print("form.errors",form.errors)
regresponse["msg_errors"]=form.errors
return HttpResponse(json.dumps(regresponse))

views.py

forms.py

 #!usr/bin/env python
# -*- coding:utf-8 -*-
from app01 import models
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import ValidationError
from django.core.validators import RegexValidator
class RegisterForm(Form):
username = fields.CharField(
required=True,
max_length=16,
min_length=3,
error_messages={
"required": "用户名不能为空",
"max_length": "长度不能大于16",
"min_length": "长度不能小于3",
},
widget=widgets.TextInput({"placeholder":"请您输入用户名","class":"form-control"})
)
password = fields.CharField(
required=True,
max_length=16,
min_length=3,
error_messages={
"required": "密码不能为空",
"max_length": "长度不能大于16",
"min_length": "长度不能小于3",
},
widget=widgets.PasswordInput({"placeholder":"请您输入数字与字母组合的密码","class":"form-control"})
)
password_again = fields.CharField(
required=True,
max_length=16,
min_length=3,
error_messages={
"required": "密码不能为空",
"max_length": "长度不能大于16",
"min_length": "长度不能小于3",
},
widget=widgets.PasswordInput({"placeholder": "请您再次输入密码", "class": "form-control"})
)
email = fields.EmailField(
required=True,
error_messages={
"required":"邮箱不能为空",
"invalid":"邮箱格式有误"
},
widget = widgets.EmailInput({"placeholder": "请输入您的邮箱", "class": "form-control"})
)
tel = fields.CharField(
required=True,
max_length=11,
min_length=11,
error_messages={
"required":"手机号码不能为空",
"max_length":"长度必须是11位,请你正确输入",
"min_length":"长度必须是11位,请你正确输入",
},
validators=[RegexValidator("\d+","密码只能是数字")],
widget=widgets.TextInput({"placeholder": "请您输入你的电话,要求11位哦", "class": "form-control"})
) #自定义用户名验证:局部钩子
def clean_username(self):
username = self.cleaned_data.get("username")
valid = models.UserInfo.objects.filter(username = username).first()
if valid:
raise ValidationError("用户名已存在")
return username
#自定义密码验证:
def clean_password(self):
password = self.cleaned_data.get("password")
if password.isdigit():
raise ValidationError("密码不能是纯数字")
else:
return password
#自定义全局钩子:验证两次密码是否一致
def clean(self):
if self.cleaned_data.get("password") == self.cleaned_data.get("password_again"):
return self.cleaned_data
else:
raise ValidationError("两次密码不一致")

forms.py

template

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/reg.css">
</head>
<body>
{#导航条#}
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container pull-left">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">博客园</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active c1"><a href="#">首页 <span class="sr-only">(current)</span></a></li>
<li class="active c1"><a href="#">登录</a></li>
<li class="active c1"><a href="#">注册</a></li>
<li class="active c1"><a href="#">帮助</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<h2>注册新用户</h2>
<hr>
<div class="container">
<div class="row left">
<div class="col-md-6 col-md-offset-1">
<form action="/register/" method="post" novalidate enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="password" class="control-label">用户名:</label>
<div>{{ form.username }}<span></span></div>
</div>
<div class="form-group">
<label for="password" class="control-label">密码:</label>
<div>{{ form.password }}<span></span></div>
</div>
<div class="form-group">
<label for="password" class="control-label">确认密码:</label>
<div>{{ form.password_again }}<span></span></div>
</div>
<div class="form-group">
<label for="email" class="control-label">邮箱:</label>
<div>{{ form.email }}<span></span></div>
</div>
<div class="form-group">
<label for="tel" class="control-label">手机号:</label>
<div>{{ form.tel }}<span></span></div>
</div>
<div class="form-group avatar">
<label for="avatar">头像:</label>
<img src="/static/image/default.png" alt="" class="avatar_img">
<input type="file" id="avatar" name="avatar_file" class="avatar_file">
</div>
<button type="button" class="btn btn-primary registr_btn">注册</button><span class="xxx"></span>
</form>
</div>
</div>
<div class="right">
<img src="/static/image/rigth.png" alt="">
</div>
</div> <script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
<script>
$(function () {
//给注册按钮增加事件
$(".registr_btn").click(function () {
var formData=new FormData();
formData.append("username",$("#id_username").val());
formData.append("email",$("#id_email").val());
formData.append("tel",$("#id_tel").val());
formData.append("password",$("#id_password").val());
formData.append("password_again",$("#id_password_again").val());
formData.append("avatar_img",$("#avatar")[0].files[0]);
console.log("=========",formData); //先清除错误信息
$(".pull-right").html("");
$(".pull-right").parent().removeClass("has-error");
$.ajax({
url:"/register/",
type:"POST",
headers: {"X-CSRFToken": $.cookie('csrftoken')},
data:formData,
contentType:false,
processData:false,
success:function (data) {
{# console.log(data);#}
var data = JSON.parse(data);
if(data["user"]){ //或者也可以用data.user
$(".xxx").html("注册成功");
window.location.href="/login/";
}
else {
console.log(data.msg_errors); //拿到的是所有的错误信息
$.each(data.msg_errors,function (i,v) {
console.log(i,v);
$span = $("<span>");//创建一个span标签,方便提示错误信息的时候用
$span.addClass("pull-right").css("color","red"); //设置样式居右并且字体颜色为红色
$span.html(v[0]);//设置span里面的字体
$("#id_"+i).after($span).parent().addClass("has-error");//吧span标签放到每个input的后面显示并且让他的父亲变红,增加一个has-error的类 if (i=="__all__"){
$("#id_password_again").after($span)
}
});
}
}
})
}); //头像预览
$(".avatar_file").change(function () {
var ele_file = $(this)[0].files[0]; //当前选中的文件
var reader = new FileReader();
reader.readAsDataURL(ele_file); //对应找到打开的url
reader.onload=function () {
{# 方式一#}
$(".avatar_img").attr("src",this.result) ; //this.result是上面找到的url
{# 方式二#}
{# $(".avatar_img")[0].src=this.result; //设置图片属性#}
}
})
})
</script>
</body>
</html>

register.html

 .c1 {
margin-right: 10px;
} h2 {
margin-top: 100px;
margin-left: 280px;
}
.left{
position: relative;
}
.right{
width: 270px;
height: 294px;
position: absolute;
top: 197px;
left: 886px;
}
.registr_btn{
width: 100px;
margin-left: 200px;
}
.avatar{
position: relative;
width: 70px;
height: 70px;
}
.avatar_img,.avatar_file{
position: absolute;
width: 70px;
height: 70px;
top: 0;
left: 46px;
}
.avatar_file{
opacity: 0;
}

reg.css

 效果截图

利用Form组件和ajax实现的注册的更多相关文章

  1. Django【第23篇】:利用Form组件和ajax实现的注册

    利用Form组件和ajax实现的注册 一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面 ...

  2. Django-利用Form组件和ajax实现的注册

    利用Form组件和ajax实现的注册 一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面 ...

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

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

  4. Django框架之Ajax和form组件

    一.Django框架之查漏补缺 1)models,字段概况 name = models.CharField(max_length=) age = models.IntegerField() price ...

  5. [oldboy-django][2深入django]Form组件功能: 数据格式验证 + 保留上次输入的值

    1 需求:登录或者注册页面存在以下问题 - 无法记住上次提交的内容,(如果有很多输入项,这样正确项不必重复输入,错误项也能提示错误信息)- 重复进行提交数据的校验(数据是否为空,长度大小等等) 2 d ...

  6. Django(十六)Form组件扩展

    http://www.cnblogs.com/wupeiqi/articles/6144178.html Form组件 - form表单(验证:保留上次内容) - - Ajax(验证:无需上次内容) ...

  7. 【Django】Form组件

    目录 Form组件介绍 常用字段与插件 Form组件中所有内置字段 从数据库中获取数据 校验示例 检验手机号是否合法 方式一(基本操作) 方式二(自定义验证规则) 方式三(利用钩子) 验证密码一致性 ...

  8. Python学习笔记整理总结【Django】:Form组件

     Form组件  Django的Form主要具有一下几大功能: --生成HTML标签 --验证用户数据(显示错误信息) --HTML Form提交保留上次提交数据 --初始化页面显示内容 1.内置字段 ...

  9. Django学习笔记之利用Form和Ajax实现注册功能

    一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...

随机推荐

  1. 【mmall】mybatis三剑客

    mybatis-generator mybatis-plugin Mybatis Plugin插件安装破解及使用:http://blog.csdn.net/u011410529/article/det ...

  2. s9.16作业,员工信息表

    转载https://blog.csdn.net/qq_35883464/article/details/83151464 实现员工信息表文件存储格式如下:id,name,age,phone,job1, ...

  3. mysql 查询优化 ~ explain与索引失效

    一 explain  1 扫描行数根据的是表的统计元数据  2 索引的元数据具体指的就是show index from查到的索引的区分度,索引的区分度越高越好   3 表的元数据是定期收集,所以可能不 ...

  4. 资源中心的ES 服务的COM.IFLYTEK.ERSP.API.RESOURCEAPI 接口注册ZOOKEEPER失败,解决记录

    No provider available for the service com.iflytek.ersp.api.ResourceApi from the url zookeeper://zook ...

  5. 一次悲催的nginx转发白屏经历

    背景 公司还有一个学习平台,由于公网地址问题,所以想用nginx转发一下,首先后端地址访问时没有问题的,一切正常. 用nginx转发后,访问nginx代理地址悲催了,出现了白屏. 排查过程 首先贴出来 ...

  6. CentOS7开启防火墙及特定端口

    开启防火墙服务 以前为了方便,把防火墙都关闭了,因为现在项目都比较重要,害怕受到攻击,所以为了安全性,现在需要将防火墙开启,接下来介绍一下步骤. 1, 首先查看防火墙状态: firewall-cmd ...

  7. 【转】MySQL用户管理及SQL语句详解

    [转]MySQL用户管理及SQL语句详解 1.1 MySQL用户管理 1.1.1 用户的定义 用户名+主机域 mysql> select user,host,password from mysq ...

  8. init级别

    新年第一天从温习记模糊的旧知识开始: init级别包含0-6: 0:关机 1:单用户(Root Only) 2:多用户(不包含Net File System 3:多用户(完全) 4:安全模式 5:桌面 ...

  9. Python运维开发基础02-语法基础【转】

    上节作业回顾(讲解+温习60分钟) #!/bin/bash #user login User="yunjisuan" Passwd="666666" User2 ...

  10. vue之登录和token处理

    应用场景一 Vue刷新token,判断token是否过期.失效,进行登录判断跟token值存储 刷新token和token是否过期的操作都是由后端实现,前端只负责根据code的不同状态来做不同的操作: ...