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 ...
随机推荐
- [SQL Server]SQL行转列
SELECT * FROM (select ActionTargetType+actiontype as TypeResult, COUNT(RowGuid) as Number from BanJi ...
- 15. DML, DDL, LOGON 触发器
触发器可以理解为由特定事件触发的存储过程, 和存储过程.函数一样,触发器也支持CLR,目前SQL Server共支持以下几种触发器: 1. DML触发器, 表/视图级有效,可由DML语句 (INSER ...
- 1. 跟踪标记 (Trace Flag) 1117, 1118 文件增长及空间分配方式
跟踪标记:1117 功能: 默认,同一个文件组下的多个文件,如果某个文件没有可用空间,且设置了自动增长,则该文件自动增长,其他文件大小保持不变: 开启后,同一文件组下的多个文件,如果某个文件没有可用空 ...
- 有序字典(OrderedDict)、默认字典(defaultdict)内置函数
http://www.cnblogs.com/wupeiqi/articles/5115190.html import collections do = collections.OrderedDict ...
- 一、Linux概述 二、Linux的安装 三、Linux的常用命令(重点)
一.Linux概述###<1>操作系统 OS,管理和控制 计算机的 硬件和软件资源的 计算机程序. 最基本的系统软件. 是用户和计算机交互的桥梁,是硬件和软件交互的桥梁. 操作系统:she ...
- Scala编程之访问修饰符
private ,protected,public,在不加前两者声明时为public为公共式访问: private为私有式访问:protected为家族式访问,与Java一致. object Oute ...
- ZT 内地20年经典电视剧大全
内地20年经典电视剧大全 片尾曲:<故事就是故事> 演唱:戴娆 我听爷爷讲了一个故事 故事里的事是那昨天的事 故事里有好人也有坏人 故事里有好事也有坏事 故事里有多少是是非非 故事 ...
- Java基础面试题(Hibernate)
Hibernate是一个什么样的框架? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hi ...
- 【转载】Java 集合框架
http://wangkuiwu.github.io/2012/02/03/collection-03-arraylist/ 网上比较全的Java集合框架教程. 注:transient是Java语言的 ...
- awk.md
简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的行编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分 ...