基于forms组件和Ajax请求的注册功能(代码)

发布时间 2023-08-19 16:29:36作者: 路过不说话

前端

 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