2018.7.9-注册及头像预览
谈一谈今天围绕form表单中遇到的问题
简单的form表单的创建这里就不多说了,首先我遇到的是一个验证码验证的问题,由于form表单需要写的东西很多,我将它单独做成了一个模块

贴上注册表单的内容:
class RegisterForm(Form):
"""
注册表单
"""
username = fields.CharField(
widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '填写用户名...'}),
)
password = fields.CharField(
widget=widgets.PasswordInput(attrs={'class': 'form-control', 'placeholder': '填写密码...'}),
)
password2 = fields.CharField(
widget=widgets.PasswordInput(attrs={'class': 'form-control', 'placeholder': '确认密码...'}),
)
email = fields.EmailField(
widget=widgets.EmailInput(attrs={'class': 'form-control', 'placeholder': '填写邮箱...'}),
)
avatar = fields.FileField(
widget=widgets.FileInput(attrs={'class': 'file_input_style', 'id': 'imgSelect'})
)
code = fields.CharField(
widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '填写验证码...'})
)
这个模块中要验证验证码的真确性就必须获取用户输入的验证码和存在服务器session中的验证码的内容,获取用户输入的验证码很简单,创建clean_code函数:
def clean_code(self):
input_code = self.cleaned_data.get('code') # 取得用户输入的值
这样便获取到了用户输入的验证码,到了获取服务器session这个难题,要获取session就必须获取到request参数,其实可以写一个RegisterForm的构造方法,在用户提交的时候将request传入RegisterForm的构造方法,这样便的得到了request,构造方法如下:
"""
写构造方法封装request,用来取得request中的信息
"""
def __init__(self, request, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs) # 传值到父类的构造方法
self.request = request # 封装request到子类
获取到session后得到code的值和用户输入的值进行比较即可:
"""
用来验证验证码是否正确
"""
def clean_code(self):
input_code = self.cleaned_data.get('code') # 取得用户输入的值
session_code = self.request.session.get('code') # 取得服务器session中的code的值
if input_code.upper() == session_code.upper():
return input_code
raise ValidationError('验证码错误!')
后面就是验证两次密码的一致性,主要的难题就是能将错误信息输出到password2对应的字段,进过查询利用add_error这个函数可以很轻松的解决这个问题:
"""
用来验证两次输入的密码是否相同
"""
def clean(self):
pwd1 = self.cleaned_data.get('password')
pwd2 = self.cleaned_data.get('password2')
if pwd1 == pwd2:
return self.cleaned_data
self.add_error('password2', ValidationError('两次输入的密码不一致!')) # 添加错误信息到password2字段中
头像预览的相关问题
头像上传方面的问题有三种解决方法:
1.当用户选择了头像后将用户选择的头像上传到服务器的临时目录,然后在页面获取服务器的临时目录中的内容具体实现如下:
利用ajax获取并发送头像,接着接收图片在服务器上的路径:
function bindAvatar3() {
$('#imgSelect').change(function () {
var obj = $(this)[0].files[0];
var formImg = new FormData();
formImg.append('img_upload', obj);
$.ajax({
url: '/head_temporary_save/',
type:'POST',
data: formImg,
processData: false, // 提交的时候不会序列化 data
contentType: false, //去除协议头
success:function (args) {
$('#previewImg').attr('src', '/'+args); //得到服务器返回的图片路径更新到页面上
}
})
})
}
服务器上接收页面发送的图片并保存的方法:
@csrf_exempt # 解除csrf保护
def head_temporary_save(request):
file = request.FILES.get('img_upload') # 得到前台发送过来的图片文件
file_path = os.path.join('static/img/temporary', file.name) # 得到服务器图片临时目录
with open(file_path, 'wb') as f:
for chunk in file.chunks():
f.write(chunk) # 写文件
return HttpResponse(file_path) # 返回图片路径
2.利用浏览器缓存来解决头像的临时保存的问题主要就是利用window.URL.createObjectURL方法:
{#利用浏览器缓存做介质存储图片#}
function bindAvatar1() {
$('#imgSelect').change(function () {
var obj = $(this)[0].files[0]; // 取到文件对象
var v = window.URL.createObjectURL(obj);
$('#previewImg').attr('src', v); // 替换图片资源路径
$('#previewImg').load(function () { // 等待图片读取完毕后释放资源
window.URL.revokeObjectURL(v);
});
})
}
3.利用系统缓存解决头像的临时保存的问题主要就是利用window.FileReader方法:
{#利用电脑内存做介质存储图片#}
function bindAvatar2() {
$('#imgSelect').change(function () {
var obj = $(this)[0].files[0];
var reader = new FileReader();
reader.onload = function (e) {
$('#previewImg').attr('src', this.result);
};
reader.readAsDataURL(obj);
})
}
总的来说,下面两种方法对浏览器的要求比较高,第一种方法虽然占用服务器资源,但是它的兼容性是最好的,在实际运用中,三种方法都用上才是最好的选择,可以通过判断是否有需要的方法的技巧来判断用户浏览器的兼容性:
function bindAvatar() {
if (window.URL.createObjectURL) { // 如果存在window.URL.createObjectURL方法
bindAvatar1();
} else if (window.FileReader) { // 如果存在window.FileReader方法
bindAvatar2()
} else {
bindAvatar3();
}
}
浙公网安备 33010602011771号