• 报障系统概要


    1.注册页面头像预览

    方式一:

    var obj = $(this)[0]  jQuery对象转化成DOM对象

    var obj = $(this)[0].files 

    var obj = $(this)[0].files[0];  获取上传文件的文件对象

    <script>
        $(function () {
            bindAvatar1();
        });
        function bindAvatar1() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
                console.log(obj);
            })
        }
    </script>

    方式二:

    window.URL.createObjectURL
    function () { [native code] }

    <script>
    $(function () {
    bindAvatar2();
    });
    /*
    本地ajax上传
    */
    function bindAvatar2() {
    $('#imgFile').change(function () {
    var obj = $(this)[0].files[0]; #先创建文件对象
    //ajax发送到后台,并获取路径
    //img.src = 获取路径
    var v = window.URL.createObjectURL(obj); #获取要上传的图片文件路径
    $('#previewImg').attr('src',v); 把路径赋值给src
    })
    }

    如果上传图片到内存立即释放,会出现报错(window.URL.revokeObjectURL(v);)

        function bindAvatar2() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
                //ajax发送到后台,并获取路径
                //img.src = 获取路径
                var v = window.URL.createObjectURL(obj);
                $('#previewImg').attr('src',v);
                window.URL.revokeObjectURL(v);
            })
        }
    View Code
    function bindAvatar2() {
        $('#imgFile').change(function () {
            var obj = $(this)[0].files[0];
            //ajax发送到后台,并获取路径
            //img.src = 获取路径
            var v = window.URL.createObjectURL(obj);
            $('#previewImg').attr('src',v);
            $('#previewImg').load(function () {
                window.URL.revokeObjectURL(v);
            });
        })
    }
    function bindAvatar2改版

    加载完成之后释放就能正常显示了

    方式三:onload事件

        $(function () {
            bindAvatar3();
        });
        /*
        本地ajax上传
         */
        function bindAvatar3() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
                //ajax发送到后台,并获取路径
                //img.src = 获取路径
                var reader = new FileReader();
                reader.readAsDataURL(obj);
                reader.onload = function(){
                    $('#previewImg').attr('src',this.result);
                }
            })
        }

    window.URL.createObjectURL
    function () { [native code] }

    做if判断(if,else if,else) 用方式二和方式三兼容性较差,但是都是上传图片到内存,减轻图片上传到服务器的压力,方式一兼容性较好。
    <script>
        $(function () {
            bindAvatar();
        });
        /*
        本地ajax上传
         */
        function bindAvatar() {
            if(window.URL.createObjectURL){
                bindAvatar2();
            }else if(window.FileReader){
                bindAvatar3();
            }else{
                bindAvatar1();
            }
        }
        function bindAvatar1() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
    {#            console.log(obj);#}
                //ajax发送到后台,并获取路径
                //img.src = 获取路径
            })
        }
    function bindAvatar2() {
        $('#imgFile').change(function () {
            var obj = $(this)[0].files[0];
            //ajax发送到后台,并获取路径
            //img.src = 获取路径
            var v = window.URL.createObjectURL(obj);
            $('#previewImg').attr('src',v);
            $('#previewImg').load(function () {
                window.URL.revokeObjectURL(v);
            });
        })
    }
        function bindAvatar3() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
                //ajax发送到后台,并获取路径
                //img.src = 获取路径
                var reader = new FileReader();
    {#            console.log('1');#}
                reader.readAsDataURL(obj);
                reader.onload = function(e){
    {#                console.log('2');#}
                    $('#previewImg').attr('src',this.result);
                }
            })
        }
    
    </script>

    方式四:FormData上传:

    <script>
        $(function () {
            bindAvatar4();
        });
        /*
         本地ajax上传
         */
    
        function bindAvatar4() {
            $('#imgFile').change(function(){
                //$(this)[0]  #jQuery对象变成DOM对象
                //$(this)[0].files #获取上传当前文件的上传对象
                //$(this)[0].files[0]   #获取上传当前文件的上传对象的某个对象
                var obj = $(this)[0].files[0];
                console.log(obj);
                //ajax 发送给后台获取头像路径
                var formdata = new FormData();//创建一个对象
                formdata.append("file",obj);
                var xhr = new XMLHttpRequest();
                xhr.open("POST","/register/");
                xhr.send(formdata);
    
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        var file_path = xhr.responseText;
                        console.log(file_path);
                        $("#previewImg").attr("src","/"+file_path)
                    }
                }
            })
        }
    
    </script>

    2.注册页面

    定义一个RegisterForm类和register函数:

    - Form组件中通过构造方法可以封装自己想要的值
    from django.forms import Form
    from django.forms import fields
    from django.forms import widgets
    from django.core.exceptions import ValidationError
    from django.core.validators import RegexValidator
    from app01 import models
    
    class RegisterForm(Form):
        username = fields.CharField(
            required=True,
            widget=widgets.TextInput(
                attrs={'class':'form-control','placeholder':'用户名为6-10个字符'}
            ),
            min_length=6,
            max_length=10,
            strip=True,
            error_messages={
                'required': '用户名不能为空',
                'min_length':'用户名至少为6个字符',
                'max_length':'用户名不超过10个字符',
            },
        )
        password = fields.CharField(
            required=True,
            widget=widgets.PasswordInput(
                attrs={'class':'form-control','placeholder':'密码为8-12个字符'}
            ),
            min_length=8,
            max_length=12,
            strip=True,
            validators=[
                RegexValidator(r'((?=.*d))^.{8,12}$','必须包含数字'),
                RegexValidator(r'((?=.*[a-zA-Z]))^.{8,12}','必须包含字母'),
                # RegexValidator(r'((?=.*[^a-zA-Z0-9]))^.{8,12}','必须包含特殊字符'),
                # RegexValidator(r'^.(s){8,12}','必须包含空格'),
            ],#用于对密码的正则验证
            error_messages={
                'required': '密码不能为空',
                'min_length':'密码不能少于8个字符',
                'max_length':'密码最多为12个字符!',
            }
        )
        password_again = fields.CharField(
            required=True,
            widget=widgets.PasswordInput(
                attrs={'class':'form-control','placeholder':'密码为8-12个字符'}
            ),
            min_length=8,
            max_length=12,
            strip=True,
            error_messages={'required':'请再次输入密码!',}
        )
        nickname = fields.CharField(
            required=True,
            widget=widgets.TextInput(
                attrs={'class':'form-control','placeholder':'请输入昵称'}
            )
        )
        email = fields.EmailField(
            required=True,
            widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'请输入邮箱'}),
            # strip=True,
            # error_messages={'required':'邮箱不能为空','invalid':'请输入正确的邮箱格式'},
        )
        avatar = fields.FileField(widget=widgets.FileInput(attrs={'id':'imgFile','class':'f1'}))
        code = fields.CharField(widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'请输入验证码'}))
        def clean_username(self):
            #对于username扩展验证,查看是否存在
            username = self.cleaned_data['username']
            users = models.UserInfo.objects.filter(username=username).count()
            if users:#如果用户名已存在
                raise ValidationError('用户名已经存在!')
            return username
        def clean_email(self):
            #对于email的扩展验证,查看是否存在
            email = self.cleaned_data['email']
            email_count = models.UserInfo.objects.filter(email=email).count()
            if email_count:
                raise ValidationError('邮箱已经存在!')
            return email
        # def _clean_password(self):#验证两次输入密码是否一致
        #     password1 = self.cleaned_data['password']
        #     password2 = self.cleaned_data['password_again']
        #     if password1 and password2:
        #         if password1 != password2:
        #             raise ValidationError('您两次输入的密码不一致')
    
        def __init__(self,request,*args,**kwargs):#构造方法,传request参数
            super(RegisterForm,self).__init__(*args,**kwargs)#完成原有form功能以外
            self.request = request#再封装一个request
    
        def clean_code(self):
            input_code = self.cleaned_data['code']
            session_code = self.request.session.get('code')#session取验证码
            if input_code.upper() == session_code.upper():#验证相等时
                return input_code#
            raise ValidationError('验证码错误')
    
        def clean(self):  # 验证两次输入密码是否一致
            p1 = self.cleaned_data.get('password')
            p2 = self.cleaned_data.get('password_again')
            if p1 == p2:
                # return self.cleaned_data
                return None
            # else:
            #     raise ValidationError('密码不一致')
            self.add_error("password_again",ValidationError('密码不一致')) #在页面的指定字段添加错误信息
       """
        Django源码添加错误信息
        # except ValidationError as e:
        # self.add_error(name, e)
       """
        # def clean(self):
        #     #基于form对象的验证,字段全部验证通过会调用clean函数验证
        #     self._clean_password()#调用函数
        #     p1 = self.cleaned_data['password']
        #     p2 = self.cleaned_data['password_again']
        #     return p2
    
                
    forms.py RegisterForm类
    def register(request):
        """
        用户注册
        :param request:
        :return:
        """
        if request.method == "GET":
            obj = RegisterForm(request)
            return render(request,'register.html',{'obj':obj})
        else:
            #验证码
            obj = RegisterForm(request,request.POST,request.FILES)
            if obj.is_valid():
                pass
            else:
                # print(obj.errors['__all__'])
                # print(obj.errors[NON_FIELD_ERRORS])
                """
                <ul class="errorlist nonfield"><li>密码不一致</li></ul>
                <ul class="errorlist nonfield"><li>密码不一致</li></ul>
               """
                #obj.errors是一个字典
                # - 对于Form组件错误信息
                """
                {
                    __all__: [错误1,错误2]
                user: [错误1,错误2]
                password: [错误1,错误2]
                }
                """
    
            return render(request,'register.html',{'obj':obj})
    register函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>注册页面</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
        <style>
            .register {
                 600px;
                margin: 0 auto;
                padding: 20px;
                margin-top: 80px;
            }
            .f1{
                position: absolute;
                height: 80px;
                 80px;
                top: 0;
                left: 0;
                opacity: 0
            }
        </style>
    </head>
    <body>
    <div class="register">
        <h3>用户注册</h3>
    
        <form class="form-horizontal" method="POST" target="ifr" action="/register/" enctype="multipart/form-data">
    {#        <h3>{{ obj.non_field_errors }}</h3>#}
            {% csrf_token %}
            <div style="position: relative; 80px;height: 80px">
                <img id="previewImg" style=" 80px;height: 80px" src="/static/images/default.png">
    {#            <input id="imgFile" class="f1" style="" type="file">#}
                {{ obj.avatar }}
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">用户名</label>
                <div class="col-sm-10">
    {#                <input type="text" class="form-control" id="inputEmail3" placeholder="用户名" name="user">#}
                    {{ obj.username }}{{ obj.errors.username.0 }}
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
    {#                <input type="password" class="form-control" placeholder="密码" name="pwd">#}
                    {{ obj.password }}{{ obj.errors.password.0 }}
                    <span class="pwd1"></span>
                </div>
            </div>
    
            <div class="form-group">
                <label class="col-sm-2 control-label">确认密码</label>
                <div class="col-sm-10">
    {#                <input id="password" type="password" class="form-control" placeholder="确认密码" name="pwd2">#}
                        {{ obj.password_again }}{{ obj.errors.password_again.0 }}{{ obj.non_field_errors }}
                    <span class="pwd2"></span>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">昵称</label>
                <div class="col-sm-10">
    {#                <input id="password_again" type="password" class="form-control" placeholder="昵称" name="nickname">#}
                    {{ obj.nickname }}{{ obj.errors.nickname.0 }}
                </div>
            </div>
    
            <div class="form-group">
                <label class="col-sm-2 control-label">邮箱</label>
                <div class="col-sm-10">
    {#                <input type="text" class="form-control" placeholder="邮箱" name="email">#}
                                        {{ obj.email }}{{ obj.errors.email.0 }}
                </div>
            </div>
    
            <div class="form-group">
                <label class="col-sm-2 control-label">验证码</label>
                <div class="col-sm-5">
    {#                <input type="text" class="form-control" placeholder="验证码" name="Verification Code">#}
                                        {{ obj.code }} {{ obj.errors.code.0 }}
                </div>
    
                <div class="col-sm-5">
                    <img style=" 120px;height: 30px" src="/check_code/">
                </div>
            </div>
    
    
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <input type="submit" class="btn btn-default" value="注册"/>
                </div>
            </div>
        </form>
    
    </div>
    
    <script src="/static/jquery-3.2.1.js"></script>
    <script>
        $(function () {
            bindAvatar();
        });
        /*
         本地ajax上传
         */
        function bindAvatar() {
            if (window.URL.createObjectURL) {
                bindAvatar2();
            } else if (window.FileReader) {
                bindAvatar3();
            } else {
                bindAvatar1();
            }
        }
        function bindAvatar1() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
                {#            console.log(obj);#}
                //ajax发送到后台,并获取路径
                //img.src = 获取路径
            })
        }
        function bindAvatar2() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
                //ajax发送到后台,并获取路径
                //img.src = 获取路径
                var v = window.URL.createObjectURL(obj);
                $('#previewImg').attr('src', v);
                $('#previewImg').load(function () {
                    window.URL.revokeObjectURL(v);
                });
            })
        }
        function bindAvatar3() {
            $('#imgFile').change(function () {
                var obj = $(this)[0].files[0];
                //ajax发送到后台,并获取路径
                //img.src = 获取路径
                var reader = new FileReader();
                {#            console.log('1');#}
                reader.readAsDataURL(obj);
                reader.onload = function (e) {
                    {#                console.log('2');#}
                    $('#previewImg').attr('src', this.result);
                }
            })
        }
    
        function bindAvatar4() {
            $('#imgFile').change(function(){
                //$(this)[0]  #jQuery对象变成DOM对象
                //$(this)[0].files #获取上传当前文件的上传对象
                //$(this)[0].files[0]   #获取上传当前文件的上传对象的某个对象
                var obj = $(this)[0].files[0];
                console.log(obj);
                //ajax 发送给后台获取头像路径
                var formdata = new FormData();//创建一个对象
                formdata.append("file",obj);
                var xhr = new XMLHttpRequest();
                xhr.open("POST","/register/");
                xhr.send(formdata);
    
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        var file_path = xhr.responseText;
                        console.log(file_path);
                        $("#previewImg").attr("src","/"+file_path)
                    }
                };
            })
        }
    
    </script>
    
    </body>
    </html>
    register.html
    
    
    首先定义构造方法,使后端可以直接通过session取值,省去很多麻烦
    def __init__(self,request,*args,**kwargs):#构造方法,传request参数
    super(RegisterForm,self).__init__(*args,**kwargs)#完成原有form功能以外
    self.request = request#再封装一个request
    def register(request):
    """
    用户注册
    :param request:
    :return:
    """
    if request.method == "GET":
    obj = RegisterForm(request)
    return render(request,'register.html',{'obj':obj})
    else:
    #验证码
    obj = RegisterForm(request,request.POST,request.FILES) #这里相应传一个request参数
    if obj.is_valid():
    pass
    else:
    # print(obj.errors['__all__'])
    # print(obj.errors[NON_FIELD_ERRORS])
    """
    <ul class="errorlist nonfield"><li>密码不一致</li></ul>
    <ul class="errorlist nonfield"><li>密码不一致</li></ul>
    """
    #obj.errors是一个字典
    # - 对于Form组件错误信息
    """
    {
    __all__: [错误1,错误2]
    user: [错误1,错误2]
    password: [错误1,错误2]
    }
    """

    return render(request,'register.html',{'obj':obj})
    在RegisterForm类中自定义clean_code函数
    1.显示验证码错误信息
    def clean_code(self):
    input_code = self.cleaned_data['code']
    session_code = self.request.session.get('code')#session取验证码
    if input_code.upper() == session_code.upper():#验证相等时
    return input_code#
    raise ValidationError('验证码错误')
    2.验证密码是否一致
    def clean(self):  # 验证两次输入密码是否一致
    p1 = self.cleaned_data.get('password')
    p2 = self.cleaned_data.get('password_again')
    if p1 == p2:
    # return self.cleaned_data
    return None
    # else:
    # raise ValidationError('密码不一致')
    self.add_error("password_again",ValidationError('密码不一致'))

    前端HTML获取错误信息 {{ obj.non_field_errors }}

    class RegisterForm(Form):
        username = fields.CharField(
            widget=widgets.TextInput(attrs={'class':'form-control'})
        )
        password = fields.CharField(
            widget=widgets.PasswordInput(attrs={'class':'form-control'})
        )
        password2 = fields.CharField(
            widget=widgets.PasswordInput(attrs={'class':'form-control'})
        )
        avatar = fields.FileField(widget=widgets.FileInput(attrs={'id':"imgSelect",'class':"f1"  }))
        code = fields.CharField(
            widget=widgets.TextInput(attrs={'class':'form-control'})
        )
    
        def __init__(self,request,*args,**kwargs):
            super(RegisterForm,self).__init__(*args,**kwargs)
            self.request = request
    Form组件中通过构造方法可以封装自己想要的值

    - 对于Form组件错误信息
    {
    __all__: [错误1,错误2]
    user: [错误1,错误2]
    password: [错误1,错误2]
    }

    # 获取整体错误信息
    - 后台
    print(obj.errors['__all__'])
    print(obj.errors[NON_FIELD_ERRORS])
    - 模板
    {{ obj.non_field_errors }}


    Django源码关于form组件验证的流程:
    is_valid()-->self.errors-->self.full_clean()-->{self._clean_fields() self._clean_form() self._post_clean()}
    from django.core.exceptions import NON_FIELD_ERRORS--->NON_FIELD_ERRORS = '__all__'

    按照源码添加错误信息
    except ValidationError as e:
    self.add_error(name, e)
    self.add_error('字段名称',错误异常对象)

    3.点击更换验证码

     

    $('#i1').attr('src','/check_code/??')

    <div class="col-sm-5">
    <img onchange="changeCode(this);" id="i1" style=" 120px;height: 30px" src="/check_code/" title="点击更新图片">
    </div>
    添加一个onchange事件
    function changeCode(ths) {
    ths.src = ths.src + "?";
    }
  • 相关阅读:
    python基础-递归
    python基础-三元表达式/列表推导式/生成器表达式
    python基础-生成器
    python基础-迭代器
    python基础-函数
    python基础-文件操作
    Docker(六)安装Red5进行rtmp推流
    Docker(五)安装Fastdfs
    Docker(四)安装Redis
    Docker(三)安装Mysql
  • 原文地址:https://www.cnblogs.com/bingabcd/p/7160970.html
Copyright © 2020-2023  润新知