使用场景:用户注册等
1、表结构
class UserInfo(AbstractUser): """ 用户信息表,继承auth认证模块中的默认表 """ nid = models.AutoField(primary_key=True) phone = models.CharField(max_length=11, unique=True) avatar = models.FileField(upload_to='static/img', default='static/img/default.png', verbose_name='头像') #upload_to值为头像存在本地的地址 create_time = models.DateTimeField(auto_now_add=True) # 注册时间 class Meta: verbose_name = '用户表' verbose_name_plural = verbose_name def __str__(self): return self.username
2、forms表单验证注册
from django import forms from blog import models from django.contrib.auth.backends import ModelBackend from django.db.models import Q from .models import UserInfo from django.core.validators import RegexValidator from django.core.exceptions import ValidationError """ 注册页表单 """ class Register(forms.Form): username = forms.CharField(max_length=15, min_length=2, label='用户名', error_messages={ 'max_length': '最长不能超过15位', 'min_length': '最短不能少于2位', 'required': '用户名不能为空' }, widget=forms.widgets.TextInput( attrs={"class": "form-control"}, ) ) password = forms.CharField(min_length=6, label='密码', error_messages={ 'min_length': '密码长度小于6', 'required': '密码不能为空' }, widget=forms.widgets.PasswordInput( attrs={"class": "form-control"}, ) ) rep_password = forms.CharField(min_length=6, label='确认密码', error_messages={ 'min_length': '确认密码长度小于6', 'required': '确认密码不能为空' }, widget=forms.widgets.PasswordInput( attrs={"class": "form-control"}, ) ) email = forms.EmailField(label='邮箱', error_messages={ 'invalid': '邮箱格式不正确', 'required': '邮箱不能为空' }, widget=forms.widgets.EmailInput( attrs={"class": "form-control"}, ) ) phone = forms.CharField( # max_length=11, label='手机号', validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^0?(13|14|15|17|18|19)[0-9]{9}', '手机号有误')], error_messages={ 'max_length': '手机号不正确', 'required': '邮箱不能为空' }, widget=forms.widgets.TextInput( attrs={"class": "form-control"}, ) ) # 重写全局的钩子函数,对确认密码做校验 def clean(self): password = self.cleaned_data.get("password") rep_password = self.cleaned_data.get("rep_password") if rep_password and rep_password != password: self.add_error("rep_password", ValidationError("两次密码不一致")) else: return self.cleaned_data # 重写局部钩子函数,对手机号进行验证 def clean_phone(self): phone = self.cleaned_data.get("phone") if models.UserInfo.objects.filter(phone=phone): raise ValidationError("手机号已被注册") else: return phone # 重写局部钩子函数,对用户名进行验证 def clean_username(self): username = self.cleaned_data.get("username") if models.UserInfo.objects.filter(username=username): raise ValidationError("用户名已被注册") else: return username # 重写局部钩子函数,对邮箱进行验证 def clean_email(self): email = self.cleaned_data.get("email") if models.UserInfo.objects.filter(email=email): raise ValidationError("邮箱已被注册") else: return email
3、通过Ajax上传数据
<script> $('#id_register').on('click', function () { //注册一个formData对象 利用它来提交表单、模拟表单提交,最大用法是可以上传二进制文件,把所有数据添加到formData对象就可以 var formData = new FormData(); // 把注册数据添加到formData对象 formData.append('username', $('#id_username').val()) formData.append('password', $('#id_password').val()) formData.append('rep_password', $('#id_rep_password').val()) formData.append('email', $('#id_email').val()) formData.append('phone', $('#id_phone').val()) //把头像文件添加到formData对象 formData.append('avatar', $("#id_avatar")[0].files[0]) $.ajax({ url:'/register/', type:'post', processData: false, // 告诉jQuery不要去处理发送的数据 传文件必须设置为false contentType: false, // 告诉jQuery不要去设置Content-Type请求头 传文件必须设置为false data:formData, success:function (ret) { if (ret.state == 1){ // 如果状态码为1,代表有错误,循环存有错误信息的对象,将错误信息添加到span标签,并给输入框加上has-error样式类 //each 循环函数 $.each(ret.msg, function (k,v) { $('#id_'+k).next().text(v).parent().parent().addClass('has-error') }) }else { // 否则输入信息正确 alert('注册成功') location.href='/login/' } } }) }) // 将默认头像替换成用户选中的头像:值被修改事件 $('#id_avatar').on('change', function () { //创建一个读取文件对象 var fileReader = new FileReader() //取到当前选中的头像文件 //console.log(this.files[0]) //读取选中的头像文件 ,读取文件需要时间,需要等待读取完成才能加载到img标签中 fileReader.readAsDataURL(this.files[0]) //等待读取完毕后,将文件加载到img标签中 fileReader.onload = function () { $('#id_img').attr('src',fileReader.result) } }) </script>
4、视图views处理
def register(request): forms_obj = forms.Register() if request.method == 'POST': ret = { 'state': 0, 'msg': '', } forms_obj = forms.Register(request.POST) if forms_obj.is_valid(): # 验证通过,将数据写入数据库 forms_obj.cleaned_data.pop('rep_password') # 删除重复密码 cleaned_data存放forms对象的数据 avatar = request.FILES.get('avatar', None) # 获取头像文件 # print(avatar, type(avatar)) # 将头像 密码等,写入数据库 models.UserInfo.objects.create_user(avatar=avatar, **forms_obj.cleaned_data) return JsonResponse(ret) else: print(forms_obj.errors, type(forms_obj.errors)) # forms_obj.errors返回一个存有所有验证错误信息的对象 ret = { 'state': 1, 'msg': forms_obj.errors } return JsonResponse(ret) return render(request, 'register.html', {'forms_obj': forms_obj})
知识点:
1、forms模块的使用,手机号字段自定义正则做校验,局部钩子与全局钩子做校验。
2、Ajax上传文件的方式:利用FormData方法
3、前端预览选中的文件方式:利用FileReader方法,需要注意读取文件需要时间,需要把文件读取完毕才进行显示
4、后端接收文件及处理
扫描二维码关注公众号,回复:
9108737 查看本文章