BBS基于forms组件和Ajax请求的注册功能(代码)
前端
1 <div class="container-fluid"> 2 <div class="row"> 3 <div class="col-md-8 col-md-offset-2"> 4 <h1 class="text-center">注册</h1> 5 <form id="myform"><!--这里不用form表单提交,只是单纯用一下form标签--> 6 {% csrf_token %} 7 {% for form in form_obj %} 8 <lable for="{{ form.auto_id }}">{{ form.label }}</lable> 9 {# form.auto_id 获取forms组件渲染的标签的id值(id_字段名)形式#} 10 {{ form }} 11 <span style="color: red"></span> 12 {% endfor %} 13 <div class="form-group"> 14 <label for="myfile">上传头像 15 {% load static %} 16 <img src="{% static 'img/default.png' %}" id="myimg" alt="" width="80" style="margin-left:10px"> 17 </label> 18 <input type="file" name="avatar" id="myfile" style="display:none"> 19 </div> 20 21 <input type="button" class="btn btn-primary pull-right" value="注册" id="id_commit"> 22 </form> 23 24 </div> 25 </div> 26 </div> 27 <script> 28 29 // 将上传的头像展示到前端页面。 30 $('#myfile').change(function () { 31 // 文件阅读器对象 32 // 1 先生成一个文件阅读器对象 33 let myFileReaderObj = new FileReader(); 34 // 2 获取用户上传的头像文件 35 let fileObj = $(this)[0].files[0]; 36 console.log(fileObj) 37 // 3 将文件对象交给阅读器对象读取 38 myFileReaderObj.readAsDataURL(fileObj) //阅读完之后其实就传到后端了。 39 console.log(myFileReaderObj) 40 // 4 利用文件阅读器 将文件展示到前端页面 修改src属性 41 //等待文件阅读器加载完毕后再执行 42 myFileReaderObj.onload = function () { 43 $('#myimg').attr('src', myFileReaderObj.result) //将图片文件读取出来放到src属性后面 44 } 45 }) 46 47 // 发送ajax请求,发送的数据中既包含普通键值对,也包含文件 48 // 准备数据 49 $('#id_commit').click(function (){ 50 // 1 借助于formData对象 51 let formDataObj = new FormData(); 52 //2 添加普通键值对 53 $.each($('#myform').serializeArray(),function (index,obj){ 54 // console.log($('#myform').serializeArray()) 输出形式 1:{name: 'username', value: 'jason'} 55 // 所以将他们一一添加进fromData对象中红 56 formDataObj.append(obj.name,obj.value) 57 }) 58 // 2 添加文件数据 (也是key:value 的形式传入的) 59 formDataObj.append('avatar',$('#myfile')[0].files[0]); 60 61 // 发送请求 62 $.ajax({ 63 url:'', 64 type:'post', 65 data:formDataObj, 66 //需要指定两个关键性参数 67 contentType:false, //不需要任何编码 68 processData: false, //不用对数据进行任何处理 69 success:function (args){ 70 if (args.code == 1000){ 71 //跳转到登录界面 72 window.onclick.href = args.url 73 }else { 74 //将对应的错误提示,展示到对应的input框下面 75 $.each(args.msg,function (index,obj){ 76 //console.log(index,obj) // eg:username:array 所以 obj是一个数组 77 let targetId = '#id_'+index 78 //forms组件渲染的标签的id值都是(id_字段名)格式,所以要用拼接的方式得到id值 79 $(targetId).next().text(obj[0]).parent().addClass('has-error') 80 }) 81 } 82 } 83 }) 84 }) 85 86 //给所有的input框绑定获取焦点事件 87 $('input').focus(function () { 88 $(this).next().text('').parent().removeClass('has-error') 89 }) 90 91 92 </script>
后端逻辑
1 from django.shortcuts import render, HttpResponse, redirect 2 from app01.myforms import MyRegForm 3 from app01 import models 4 from django.http import JsonResponse 5 6 # Create your views here. 7 def register(request): 8 form_obj = MyRegForm() 9 if request.method == 'POST': 10 back_dic = {'code': 1000, 'msg': ''} 11 # 校验数据是否合法 12 # # print(request.POST) # 得到QueryDict对象(一个字典) 13 form_obj = MyRegForm(request.POST) # 将字典里面的数据传给MyRegForm进行比对,有不对的会返回出来错误(error_messages) 14 # 判断数据是否合法 15 if form_obj.is_valid(): # 该方法只有在数据全部合法的情况下才会返回true 16 clean_data = form_obj.cleaned_data # 查看所有校验过的数据,并返回(字典格式) 17 clean_data.pop('confirm_password') # 删除确认密码的数据,为下面保存数据做铺垫 18 file_obj = request.FILES.get('avatar') # 用户头像一定要判断是否传值,不能直接添加到字典中 19 # # print(file_obj) # file_obj 是图片名字 222.jpg 20 if file_obj: 21 clean_data['avatar'] = file_obj 22 # 操作数据库保存数据 23 models.UserInfo.objects.create_user(**clean_data) 24 back_dic['url'] = '/login/' # 传一个地址过去 ,注册完成后跳转到登录界面 25 else: 26 back_dic['code'] = 2000 27 back_dic['msg'] = form_obj.errors # 查看所有不符合校验规则的参数以及不符合的原因 28 return JsonResponse(back_dic) 29 return render(request, 'register.html', locals())
forms类书写
1 from django import forms 2 from app01 import models 3 4 5 # 对forms表中输入框输入的内容的限制。 6 7 8 class MyRegForm(forms.Form): 9 username = forms.CharField(label='用户名', min_length=3, max_length=8, 10 error_messages={ 11 'required': '用户名不能为空', 12 'min_length': '用户名最少三位', 13 'max_length': '用户名最大八位', 14 }, 15 # 让标签有bootstrap样式 16 widget=forms.widgets.TextInput(attrs={'class': 'form-control'}) 17 ) 18 password = forms.CharField(label='密码', min_length=3, max_length=8, 19 error_messages={ 20 'required': '密码不能为空', 21 'min_length': '密码最少三位', 22 'max_length': '密码最大八位', 23 }, 24 # 让标签有bootstrap样式 25 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}) 26 ) 27 confirm_password = forms.CharField(label='确认密码', min_length=3, max_length=8, 28 error_messages={ 29 'required': '确认密码不能为空', 30 'min_length': '确认密码最少三位', 31 'max_length': '确认密码最大八位', 32 }, 33 # 让标签有bootstrap样式 34 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}) 35 ) 36 email = forms.EmailField(label='邮箱', 37 error_messages={ 38 'required': '邮箱不能为空', 39 'invalid': '邮箱格式不正确', 40 }, 41 widget=forms.widgets.EmailInput(attrs={'class': 'form-control'}) 42 ) 43 44 # 局部钩子 校验用户名是否已经存在 45 def clean_username(self): 46 username = self.cleaned_data.get('username') 47 # 去数据库中校验 48 is_exist = models.UserInfo.objects.filter(username=username) 49 if is_exist: 50 # 提示信息 51 self.add_error('username', '用户名已存在') 52 return username 53 54 # 全局钩子:校验两次密码是否一致 55 def clean(self): 56 password = self.cleaned_data.get('password') 57 confirm_password = self.cleaned_data.get('confirm_password') 58 if not password == confirm_password: 59 self.add_error('confirm_password', '两次密码不一致') 60 return self.cleaned_data
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!