3- 功能2:基于forms组件和ajax实现注册功能
1、forms组件的注册页面

url
from django.urls import path, re_path
from blog import views
from django.views.static import serve
from cnblog import settings urlpatterns = [
re_path('^login/$', views.login, name='login'),
re_path('^get_validCode/$', views.get_validCode, name='get_validCode'),
re_path('^index/$', views.index, name='index'),
re_path('^register/$', views.register, name='register'),
]
views视图
from blog.myForms import UserForm # froms组件 def register(request):
"""
注册页面
:param request:
:return:
""" form = UserForm return render(request, "blog/register.html", {'form':form})
forms组件
from django import forms
from django.forms import widgets
from blog.models import UserInfo
from django.core.exceptions import ValidationError class UserForm(forms.Form):
user = forms.CharField(max_length=32,label="用户名",
error_messages={"required": "该字段不能为空"},
widget=widgets.TextInput(attrs={"class": "form-control"}))
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"}))
模板层
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css">
<script src="/static/js/jquery-3.2.1.min.js"></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 %}
<div class="form-group">
<label for="">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %} <div class="form-group">
<label for="">头像</label>
<img width="60" height="60" src="/static/img/default.jpg" alt="" id="avatar_img"
style="margin-left: 20px">
<input type="file" id="avatar">
</div> <input type="button" class="btn btn-success register-btn" value="注册">
</form>
</div>
</div>
</div>
</body> </html>
2、头像上传,预览功能

(1)label标签的for属性


(2)头像图像,上传文件input框,一致


(3)头像预览功能:获取input框的图片





<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css">
<script src="/static/js/jquery-3.2.1.min.js"></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 %}
<div class="form-group">
<label for="{{ field.auto_id }}">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %} <div class="form-group">
<label for="avatar">头像 <img width="60" height="60" src="/static/img/default.jpg" alt="" id="avatar_img"
style="margin-left: 20px">
<input type="file" id="avatar" style="display: none"> </label>
</div> <input type="button" class="btn btn-success register-btn" value="注册">
</form>
</div>
</div>
</div> <script type="text/javascript">
$(function () {
$('#avatar').change(function () {
//获取用户选中的文件对象
var file_obj = $(this)[0].files[0]; //获取文件对象的路径
var reader = new FileReader();
reader.readAsDataURL(file_obj); //修改img的src属性, src= 文件对象的路径
// $(this).prepend('img').attr("src", reader.result); // 等页面加载完成在执行onload
reader.onload = function () {
$("#avatar_img").attr("src", reader.result)
}
})
})
</script>
</body> </html>
3、Ajax提交formdata数据
(1)点击注册按钮


注册视图


(2)循环展示错误msg



(3)代码优化:form表单数据序列化append



4、forms组件的局部钩子,全局钩子




5、注册成功,添加数据
(1)模板层 跳转到view视图

(2)view视图层

(3)FieldFile字段


数据库保存的是文件的路径


(2)代码优化


6、media配置
Dajngo有两种静态文件:
/static/ : js,css,img
/media/ : 用户上传文件
settings配置
# MEDIA配置:与用户上传相关的配置
# 配置1:用户上传头像的文件
MEDIA_ROOT = os.path.join(BASE_DIR, "media") # 配置2:开放media目录给用户
MEDIA_URL = "/media/"
配置1:settings配置media目录


配置2:开放media目录给用户


(3)开放给用户的目录
开放给用户的目录
http://127.0.0.1:8000/static/img/default.jpg
http://127.0.0.1:8000/blog/media/avatars/mingren.jpg/


7、完整代码
主url
from django.contrib import admin
from django.urls import path, re_path, include urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^blog/', include(('blog.urls', 'blog')))
]
url
from django.urls import path, re_path
from blog import views
from django.views.static import serve
from cnblog import settings urlpatterns = [
re_path('^login/$', views.login, name='login'),
re_path('^get_validCode/$', views.get_validCode, name='get_validCode'),
re_path('^index/$', views.index, name='index'),
re_path('^register/$', views.register, name='register'), # media配置
re_path(r'^media/(?P<path>.*)/$', serve, {"document_root": settings.MEDIA_ROOT}),
]
注册views视图
from django.shortcuts import render, HttpResponse, redirect
from blog.utils.validCode import get_validCode_img # 导入验证码函数
from django.http import JsonResponse # Json数据返回到前端
from django.contrib import auth # 用户认证组件
from blog.models import UserInfo
from blog.myForms import UserForm # froms组件 def register(request):
"""
注册页面
:param request:
:return:
"""
# if request.method == 'POST':
if request.is_ajax():
response = {'user':None, "msg":None} form = UserForm(request.POST)
if form.is_valid():
response['user'] = form.cleaned_data.get("user") # 生成一条数据
user = request.POST.get("user")
pwd = request.POST.get("pwd")
email = request.POST.get("email")
avatar_obj = request.FILES.get("avatar")
print(avatar_obj) extra_fields = {}
if avatar_obj:
extra_fields["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra_fields) """
if avatar_obj:
# 快捷键 alt + f7
UserInfo.objects.create_user(username=user, password=pwd, email=email, avatar=avatar_obj)
else:
UserInfo.objects.create_user(username=user, password=pwd, email=email)
""" else:
print(form.cleaned_data)
print(form.errors)
response['msg'] = form.errors return JsonResponse(response) form = UserForm return render(request, "blog/register.html", {'form':form})
注册forms组件
from django import forms
from django.forms import widgets
from blog.models import UserInfo
from django.core.exceptions import ValidationError class UserForm(forms.Form):
user = forms.CharField(max_length=32,label="用户名",
error_messages={"required": "该字段不能为空"},
widget=widgets.TextInput(attrs={"class": "form-control"}))
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"})) # 用户名的认证
def clean_user(self):
user = self.cleaned_data.get('user') user_obj = UserInfo.objects.filter(username=user).first()
if not user_obj:
return user
else:
raise ValidationError('该用户名已经注册')
# return ValidationError('该用户名已经注册') # 不能用出现bug # 密码
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:
# return ValidationError("两次密码不一致!")
raise ValidationError("两次密码不一致!")
else:
return self.cleaned_data
注册页面模板层
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css">
<script src="/static/js/jquery-3.2.1.min.js"></script>
</head>
<body> <h3>注册页面</h3> <div class="container">
<div class="row">
<div class="col-md-6 col-lg-offset-3">
<form id="id_form">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.auto_id }}">{{ field.label }}</label>
{{ field }}
<span class="error pull-right" style="color: red"></span>
</div>
{% endfor %} <div class="form-group">
<label for="avatar">头像 <img width="60" height="60" src="/static/img/default.jpg" alt="" id="avatar_img"
style="margin-left: 20px">
<input type="file" id="avatar" style="display: none"> </label>
</div> <input type="button" class="btn btn-success register-btn" value="注册">
</form>
</div>
</div>
</div> </body> </html>
注册页面js代码
<script type="text/javascript">
$(function () {
$('#avatar').change(function () {
//获取用户选中的文件对象
var file_obj = $(this)[0].files[0]; //获取文件对象的路径
var reader = new FileReader();
reader.readAsDataURL(file_obj); //修改img的src属性, src= 文件对象的路径
// $(this).prepend('img').attr("src", reader.result); // 等页面加载完成在执行onload
reader.onload = function () {
$("#avatar_img").attr("src", reader.result)
}
})
}); //基于ajax提交数据
$(function () {
$('.register-btn').click(function () { //获取数据
var formdata = new 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("csrfmiddlewaretoken", $('[name="csrfmiddlewaretoken"]').val());
-->
var request_data = $('#id_form').serializeArray();
$.each(request_data, function (index, data) {
formdata.append(data.name, data.value)
}); formdata.append("avatar", $("#avatar")[0].files[0]); $.ajax({
url: '',
type: 'post',
contentType: false,
processData: false,
data: formdata,
success: function (data) {
console.log(data);
if (data.user) { //注册成功
location.href = "/blog/login" } else {
//清空错误信息,和div的样式
$('span.error').html("");
$(".form-group").removeClass("has-error"); //展示error_msg
$.each(data.msg, function (field, error_list) {
if (field == "__all__") {
$('#id_re_pwd').next('span').html(error_list[0]).parent('div').addClass('has-error'); } else {
$('#id_' + field).next('span').html(error_list[0]).parent('div').addClass('has-error'); }
}) } }
})
})
}) </script>
8、总结
基于forms组件和Ajax实现注册功能 # 1 基于forms组件设计注册页面 ---点击头像===点击input ---头像预览:
1 获取用户选中的文件对象
2 获取文件对象的路径
3 修改img的src属性 ,src=文件对象的路径 # 2 错误信息: views: form.erorrs # {"user":[......]} Ajax.success:
$.each(data.msg, function (field, error_list) { $("#id_" + field).next().html(error_list[0]);
$("#id_" + field).parent().addClass("has-error"); }) # 3 局部钩子和全局钩子校验
user字段不能重复
两次密码不一致 # 4 FileField与ImageFiled class UserInfo(AbstractUser): nid = models.AutoField(primary_key=True)
telephone = models.CharField(max_length=11, null=True, unique=True)
avatar = models.FileField(upload_to='avatars/', default="/avatars/default.png") avatar_obj=request.FILES.get("avatar")
user_obj=UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar=avatar_obj) Dajngo实现: 会将文件对象下载到项目的根目录中avatars文件夹中(如果没有avatar文件夹,Django会自动创建),user_obj的avatar存的是文件的相对路径。 # 5 Media 配置之MEDIA_ROOT: Dajngo有两种静态文件: /static/ : js,css,img
/media/ : 用户上传文件 class UserInfo(AbstractUser): nid = models.AutoField(primary_key=True)
telephone = models.CharField(max_length=11, null=True, unique=True)
avatar = models.FileField(upload_to='avatars/', default="/avatars/default.png") avatar_obj=request.FILES.get("avatar")
user_obj=UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar=avatar_obj) 一旦配置了
MEDIA_ROOT=os.path.join(BASE_DIR,"media") Dajngo实现: 会将文件对象下载到MEDIA_ROOT中avatars文件夹中(如果没有avatar文件夹,Django会自动创建),user_obj的avatar存的是文件的相对路径。 # 6 Media 配置之MEDIA_URl: 浏览器如何能直接访问到media中的数据 settings.py:
MEDIA_URL="/media/" urls.pt:
# media配置:
re_path(r"media/(?P<path>.*)$",serve,{"document_root":settings.MEDIA_ROOT})
3- 功能2:基于forms组件和ajax实现注册功能的更多相关文章
- 基于forms组件和Ajax实现注册功能
一.基于forms组件的注册页面设计 1.运用forms组件的校验字段功能实现用户注册 views.py: (在钩子中代码解耦,将form放在cnblog/blog/Myforms.py中) f ...
- BBS-基于forms组件和ajax实现注册功能
http://www.cnblogs.com/yuanchenqi/articles/7638956.html 1.设计注册页面 views.py from django import forms c ...
- 2.1博客系统 |基于form组件和Ajax实现注册登录
基于forms组件和Ajax实现注册功能 1 基于forms组件设计注册页面 --点击头像 === 点击input --头像预览: 修改用户选中的文件对象:获取文件对象的路径:修改img的src属性, ...
- Django学习笔记之利用Form和Ajax实现注册功能
一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...
- 总结Ajax验证注册功能的两种方式
方法一:使用jqueryForm插件提交表单注册 ①首先引入jquery和jqueryForm插件 <script type="text/javascript" src=&q ...
- forms 组件的功能和使用
forms组件 先自己实现注册功能,并且对用户输入的信息加限制条件 如果用户输入的信息不符合条件,前端展示报错信息 注册示例: 1.前端渲染标签获取用户输入 >>> 前端渲染标签 2 ...
- django之forms组件,cookie&session
forms组件 先自己实现注册功能,并且对用户输入的信息加限制条件如果用户输入的信息不符合条件,前端展示报错信息 from django.shortcuts import render,HttpRes ...
- python 全栈开发,Day78(Django组件-forms组件)
一.Django组件-forms组件 forms组件 django中的Form组件有以下几个功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显 ...
- forms组件补充与ModelForm简单使用与cookie与session
目录 forms组件钩子函数 forms组件字段参数 字段参数 validators详解 choices详解 widget详解 forms组件字段类型 ModelForm简单使用 cookie与ses ...
随机推荐
- Entity Framework之DB First方式
EF(Entity Framework的简称,下同)有三种方式,分别是:DataBase First. Model First和Code First. 下面是Db First的方式: 1. 数据库库中 ...
- 安装Window Server 2008的些配置
上次安装window server2008,由于server2008需要设置很多东西,不然用起来很不爽,就说IE吧,每次随便打开一个网页都要弹出n多窗口出来叫你添加到信任域里面!太烦人了![下面有解决 ...
- 固定UIScrollView滑动的方向
固定UIScrollView滑动的方向 一般而言,我们通过这两个参数CGRectMake以及contentSize就可以自动的让UIScrollView只往一个方向滚动.但我遇到过非常奇葩的情况,那就 ...
- NSCopying简析
NSCopying简析 用到NSCopying的时候并不多,但还是有必要知道最基本的用途,比方说数组的拷贝操作,需要注意的是,数组的拷贝操作并不是执行了 copy 方法,而是需要执行 initWith ...
- eclipse tomcat部署工程路径
C:\Users\KPL\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\day18_ ...
- C#综合揭秘——分部类和分部方法
在面向对象的“封装闭合性”开发原则中,一向提倡的是把独立的功能封装在一个类里面的!但从Visual Studio 2005开发,系统提供了一个分部类的开发方式一直受到争议,很多人认为把同一类的功能分布 ...
- APUE 12.7 取消选项
- Eclipse插件安装方法大全
1. M2e maven2插件安装 参考地址:http://www.sonatype.com/books/m2eclipse-book/reference/install-sect-marketpla ...
- 【转】.net core 一次坑爹的类库打包过程
自己遇到这个问题,记录一下,原文链接:http://www.cnblogs.com/Hai--D/p/5776463.html. 众所周知,.net core 跨平台类库引用一定要通过nuget获得. ...
- wk_06.md
IO与文件操作 文件内建函数open 内建函数open提供了初始化输入/输出(I/O)操作的通用接口.open()内建函数成功打开文件后会返回一个文件对象.open函数的语法如下: open(file ...