?
1、利用form组件建立form组件
from app01.models import UserInfo
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class UserFrom(forms.Form): #固定格式
user = forms.CharField(max_length=32,label=‘用户名‘,# 设置前端lable标签
error_messages={‘required‘:‘该字段不能为空‘},# 当用户未输入时报错信息
widget=widgets.TextInput(attrs={‘class‘:‘form-control‘})) # 设置input的type 添加类标签
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=‘电子邮箱‘,error_messages={‘required‘: ‘格式错误‘},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 user_obj:
#已被注册
raise ValidationError(‘该用户已注册‘)
else:
return user
# 建立全局钩子
def clean(self):
pwd = self.cleaned_data.get(‘pwd‘)
re_pwd = self.cleaned_data.get(‘re_pwd‘)
if pwd == re_pwd:
return self.cleaned_data
else:
raise ValidationError(‘密码不一致‘)
?
?
2、views中注册验证
def register(request):
form = UserFrom() # 生成form组件
send_info = {‘user‘:None,‘msg‘:None}
if request.method == ‘POST‘:
form_obj = UserFrom(request.POST)
if form_obj.is_valid(): # form表单进行格式校验
send_info[‘user‘] = form_obj.cleaned_data.get(‘user‘)
user = request.POST.get(‘user‘)
pwd = request.POST.get(‘pwd‘)
re_pwd = request.POST.get(‘re_pwd‘)
email = request.POST.get(‘email‘)
img = request.FILES.get(‘img‘)
# 非明文存储
UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar=img)
else:
print(form_obj.cleaned_data) # 存放了所有正确信息
print(form_obj.errors) # 存放了所有错误信息
send_info[‘msg‘] = form_obj.errors # 全局变量信息K为__all__
return JsonResponse(send_info)
return render(request,‘register.html‘,locals())
?
?
3、前端样式
<div class=‘container‘>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center">用户注册</h1>
<form >
{% csrf_token %}
{#form组件建立模型#}
{% for filed in form %}
<div class="form-group">
<label for="user">{{ filed.label }}</label>
{{ filed }}<span class="err_info pull-right"></span>
</div>
{% endfor %}
<label for="img">头像
<div>
<img src="/static/img/timg.jpg" id="image">
</div>
</label>
<input id="img" type="file" style="display: none">
<div>
<input type="button" class="btn btn-info pull-right" value="提交" id="btn">
</div>
</form>
</div>
</div>
</div>
?
?
4、jquery
<script>
$(function () {
//头象预览
$(‘#img‘).change(function () {
// 获取文件对象
var file = $(‘#img‘)[0].files[0];
// 获得文件对象的路径(文件阅读器)
var reader = new FileReader();
reader.readAsDataURL(file);//阅读文件的路径,并把结果保存在reader.result
//更改文件路径(与reader.readAsDateURL是异步操作,需要用onload加载完再执行)
reader.onload = function(){
$(‘#image‘).attr(‘src‘,reader.result)}
})
//ajax输入验证
$(‘#btn‘).click(function () {
var formdata = new FormData
formdata.append(‘user‘,$(‘#id_user‘).val()); //从form传来组件,默认id=id_组件名
formdata.append(‘pwd‘,$(‘#id_pwd‘).val());
formdata.append(‘re_pwd‘,$(‘#id_re_pwd‘).val());
formdata.append(‘email‘,$(‘#id_email‘).val());
formdata.append(‘img‘,$(‘#img‘)[0].files[0]);
formdata.append(‘csrfmiddlewaretoken‘,$(‘[name =csrfmiddlewaretoken]‘).val());
$.ajax({
url:‘‘,type:‘POST‘,contentType:false,processData:false,data:formdata,success:function (data) {
if(data.user){
location.href= ‘/login/‘
}
else{
console.log(data[‘msg‘]);
{#清空错误信息#}
$(‘.err_info‘).text(‘‘);
$(‘.form-group‘).removeClass(‘has-error‘);
{#循环打印msg中的错误信息#}
$.each(data[‘msg‘],function (msg_k,msg_v) {
{#判断是不是全局钩子#}
if(msg_k==‘__all__‘){
$(‘#id_re_pwd‘).next().text(msg_v)
$(‘#id_pwd,#id_re_pwd‘).parent().addClass(‘has-error‘)
}
$(‘#id_‘+msg_k).next().text(msg_v);
$(‘#id_‘+msg_k).parent().addClass(‘has-error‘) // 添加错误边框样式
})
}
}
})
})
})
</script>
?
?
?
重点:
1、form组件创建form组件,需要在views中生成对象obj,obj.is_vaild()进行判断
局部钩子 clean_字段名称,用于验证字段验证,异常信息以{‘字段对象’:value}写入errors字典中;
全局钩子 clean(self)用于判断密码是否一致,异常信息以{‘__all__‘ : [value,]}写入errors字典中;
所有正确信息存放在 clean_data 中;错误信息存入 errors 中
?
2、前端头象预览,
获得文件对象、获得文件路径(文件浏览器FileReader)、更换文件src(文件浏览器功能为异步操作,需利用onload)
?
3、from组件中errors信息,
循环打印之前判断,errors中是否有全局钩子报错
利用form组件在前端? id = id_组件字段名?进行拼接事件
每次请求时,需要对之前报错数据进行清空
?
4、在数据库存储文件
models中
class UserInfo
....
avatar = models.FileField(upload_to=‘avatars/‘,default=‘/avatars/default.png‘)
实例化时,avatar = avatar_obj (avatar只接收文件对象)
upload_to=‘avatars/‘ 文件会下载到项目的根目录中的avatars文件夹中(如果没有,自动生成)