关键词搜索

源码搜索 ×
×

通用的Django注册功能模块实现

发布2021-02-04浏览470次

详情内容

注册功能实现
forms组件进行表单验证;
用户头像前端实时展示;
ajax发送post请求;
应用forms组件实现用户输入信息的校验。首先在app目录下创建一个myform.py的文件。

如果你的项目至始至终只用到一个forms组件那么你可以直接建一个py文件书写即可。
但是如果你的项目需要使用多个forms组件,那么你可以创建一个myforms文件夹在文件夹内,根据forms组件功能的不同创建不同的py文件。
regform.py
loginform.py
userform.py
orderform.py

# 书写针对用户表的forms主键代码
from django import forms
from app01 import models

class MyRegForm(forms.Form):
    username = forms.CharField(label='用户名',min_length=3,max_length=8,
                               error_messages={
                                   'required':'用户名不能为空',
                                   'min_length':'用户名最少3位',
                                   'max_length':'用户名最大8位'
                               },
                               # 还需要让标签有Bootstrap样式
                               widget=forms.widgets.TextInput(attrs={'class':'form-control'})
                               )
    password = forms.CharField(label='密码',min_length=3,max_length=8,
                               error_messages={
                                   'required':'密码不能为空',
                                   'min_length':'密码最少3位',
                                   'max_length':'密码最大8位'
                               },
                               # 还需要让标签有Bootstrap样式
                               widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
                               )
    confirm_password = forms.CharField(label='确认密码',min_length=3,max_length=8,
                                       error_messages={
                                        'required':'确认密码不能为空',
                                        'min_length':'确认密码最少3位',
                                        'max_length':'确认密码最大8位'
                                    },
                                   # 还需要让标签有Bootstrap样式
                                   widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
                                   )
    email = forms.EmailField(label='邮箱',
                             error_messages={
                                 'required': '邮箱不能为空',
                                 'invalid':'邮箱格式不正确',
                             },
                             widget=forms.widgets.EmailInput(attrs={'class':'form-control'})
                             )

    # 钩子函数
    # 局部钩子:校验用户名是否已存在
    def clean_username(self):
        username = self.cleaned_data.get('username')
        # 去数据库中校验
        is_exist = models.UserInfo.objects.filter(username=username)
        if is_exist:
            # 提示信息
            self.add_error('username','用户名已存在')
        return username

    # 全局钩子:校验两次密码是否一致
    def clean(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
            self.add_error('confirm_password','两次密码不一致')
        return self.cleaned_data
        ```
然后在urls.py中配置注册页的路[python基础教程](https://www.xin3721.com/eschool/pythonxin3721/)由信息。

```csharp
from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('register/',views.register,name='reg'),
]

    在视图函数views.py中编写forms组件检验、ajax发送的post请求获取数据、调用django orm功能存储数据、将后端的处理结果返回给前端进行校验。

    from app01.myforms import MyRegForm
    from app01 import models
    from django.http import JsonResponse
    # Create your views here.
    
    def register(request):
        form_obj = MyRegForm()
        if request.method == 'POST':
            # 定义返回给前端的js数据结果
            back_dic = {"code": 1000, 'msg': ''}
            # 校验数据是否合法
            form_obj = MyRegForm(request.POST)
            # 判断数据是否合法
            if form_obj.is_valid():
                # form_obj.cleaned_data:{'username': 'zhangsan', 'password': '123456', 'confirm_password': '123456', 'email': '123@qq.com'}
                # 将校验通过的数据字典赋值给一个变量
                clean_data = form_obj.cleaned_data  
                # 将字典里面的confirm_password键值对删除
                clean_data.pop('confirm_password')  # {'username': 'zhangsan', 'password': '123456', 'email': '123@qq.com'}
                
                # 注意用户头像是一个图片的文件,request.POST中只有键值对的数据
                file_obj = request.FILES.get('avatar')
                """
                	针对用户头像一定要判断是否传值,不能直接添加到字典里面去
                	否则file_obj=None,会将数据库中默认的图片路径覆盖。
                """
                if file_obj:
                    # 向字典数据clean_data中增加一个图片头像的字段
                    clean_data['avatar'] = file_obj
                # 操作数据库保存数据
                models.UserInfo.objects.create_user(**clean_data)
                # 注册成功则跳转到登录页面
                back_dic['url'] = '/login/'
            else:
                back_dic['code'] = 2000 # 校验存在错误
                back_dic['msg'] = form_obj.errors
            # 将字典类型的数据封装成json返回到前端
            return JsonResponse(back_dic)
        return render(request,'register.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    前端的注册页面:register.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <!-- Bootstrap -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js">
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
        <title>用户注册</title>
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">注册</h1>
                <form id="myform">  <!--这里我们不用form表单提交数据 知识单纯的用一下form标签而已-->
                    {% csrf_token %}
                    {% for form in form_obj %}
                        <div class="form-group">
                            <label for="{{ form.auto_id }}">{{ form.label }}</label>
                            {{ form }}
                            <span style="color: red" class="pull-right"></span>
                        </div>
                    {% endfor %}
                    
                    <div class="form-group">
                        <label for="myfile">头像
                            {% load static %}
                            <img src="{% static 'img/default.jpg' %}" id='myimg' alt="" width="100" style="margin-left: 10px">
                        </label>
                        <input type="file" id="myfile" name="avatar" style="display: none" >
                    </div>
    
                    <input type="button" class="btn btn-primary pull-right" value="注册" id="id_commit">
                </form>
            </div>
        </div>
    </div>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    【重难点】在于书写JS处理逻辑:包括了图片上传加载、ajax发送的post请求以及后端注册结果的信息处理。

    <script>
        $("#myfile").change(function () {
            // 文件阅读器对象
            // 1 先生成一个文件阅读器对象
            let myFileReaderObj = new FileReader();
            // 2 获取用户上传的头像文件
            let fileObj = $(this)[0].files[0];
            // 3 将文件对象交给阅读器对象读取
            myFileReaderObj.readAsDataURL(fileObj)  // 异步操作  IO操作
            // 4 利用文件阅读器将文件展示到前端页面  修改src属性
            // 等待文件阅读器加载完毕之后再执行
            myFileReaderObj.onload = function(){
                 $('#myimg').attr('src',myFileReaderObj.result)
            }
        })
    
        $('#id_commit').click(function () {
            // 发送ajax请求     我们发送的数据中即包含普通的键值也包含文件
            let formDataObj = new FormData();
            // 1.添加普通的键值对
            {#console.log($('#myform').serializeArray())  // [{},{},{},{},{}]  只包含普通键值对#}
            $.each($('#myform').serializeArray(),function (index,obj) {
                {#console.log(index,obj)#}  // obj = {}
                formDataObj.append(obj.name,obj.value)
            });
            // 2.添加文件数据
            formDataObj.append('avatar',$('#myfile')[0].files[0]);
    
            // 3.发送ajax请求
            $.ajax({
                url:"",
                type:'post',
                data:formDataObj,
    
                // 需要指定两个关键性的参数
                contentType:false,
                processData:false,
    
                success:function (args) {
                    if (args.code==1000){
                        // 跳转到登陆页面
                        //window.location.href = args.url
                    }else{
                        // 如何将对应的错误提示展示到对应的input框下面
                        // forms组件渲染的标签的id值都是 id_字段名
                        $.each(args.msg,function (index,obj) {
                            {#console.log(index,obj)  //  username        ["用户名不能为空"]#}
                            let targetId = '#id_' + index;
                            $(targetId).next().text(obj[0]).parent().addClass('has-error')
                        })
                    }
                }
            })
        })
        // 给所有的input框绑定获取焦点事件
        $('input').focus(function () {
            // 将input下面的span标签和input外面的div标签修改内容及属性
            $(this).next().text('').parent().removeClass('has-error')
        })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    效果如下:
    在这里插入图片描述

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载