分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

Django 【第十七篇】使用Form组件和Ajax实现用户注册

发布时间:2023-09-06 01:43责任编辑:顾先生关键词:Ajax组件

一、注册相关的知识点

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:falseprocessData: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.pngavatar字段在数据库中保存的是: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 urlfrom django.contrib import adminfrom app01 import viewsfrom django.conf import settingsfrom django.views.static import serveurlpatterns = [ ???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}),]

  

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))

  

forms.py

#!usr/bin/env python# -*- coding:utf-8 -*-from app01 import modelsfrom django.forms import Formfrom django.forms import widgetsfrom django.forms import fieldsfrom django.core.validators import ValidationErrorfrom django.core.validators import RegexValidatorclass 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("两次密码不一致")

  

template

register.html
<!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" ?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" > ???</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>

  

reg.css
.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;}

  

 效果截图

 
 

Django 【第十七篇】使用Form组件和Ajax实现用户注册

原文地址:https://www.cnblogs.com/xiaohema/p/8456436.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved