• 博客园项目


        

    day 1 

      基于ajax,PIL实现随机图片验证码 以及geetest插件实现滑动验证码  的登录功能。

      1)生成随机验证码

      

      怎么实现呢?

      前端html代码

      贴上代码

    <div class="row">
                           <div class="col-md-6">
                               <label for="id_valid">验证码</label>
                               <input type="text" class="form-control" id="id_valid" placeholder="验证码">
                           </div>
                           <div class="col-md-6">
                               <img src="/get_valid_code/" width="250px" height="50px" alt="">            //<img src='//'>src跟一个视图函数,走这个函数,拿到一个图片,会将页面重新渲染。
                           </div>
                       </div>

      点击实现刷新

      

    <script>
        $('img').click(function () {
            console.log($(this));                    // console.log  r.fn.init [img]
            console.log($(this)[0]);                 // console.log  <img src=​"http:​/​/​127.0.0.1:​8000/​get_valid_code/​?" width=​"250px" height=​"50px" alt>​
            $(this)[0].src+='?'                      .src方法是DOM对象的方法  
        })
    </script>

      视图函数

    def get_valid_code(request):
        from PIL import Image,ImageDraw,ImageFont
        from io import BytesIO
        def get_color():
            return (random.randint(0,255),random.randint(0,255),random.randint(0,255))
        def get_char():
            random_num=str(random.randint(0,9))
            random_upper=chr(random.randint(65,90))
            random_lower=chr(random.randint(97,122))
            return random.choice([random_num,random_upper,random_lower])
        height=50
        width=250
        image=Image.new(mode='RGB',size=(width,height),color=get_color())
        print('image',image,type(image))                       #image <PIL.Image.Image image mode=RGB size=250x50 at 0x1E20FE94BA8> <class 'PIL.Image.Image'>
        draw=ImageDraw.Draw(image,mode='RGB')
        print('draw',draw,type(draw))                          #draw <PIL.ImageDraw.ImageDraw object at 0x000001E20FE94CF8> <class 'PIL.ImageDraw.ImageDraw'>
        font=ImageFont.truetype('app01/static/kumo.ttf',40)
        valid_code=''
        for i in range(6):
            char=get_char()
            valid_code+=char
            draw.text([i*40,5],char,get_color(),font=font)
        f=BytesIO()
        image.save(f,'png')
        data=f.getvalue()
        print('data',data,type(data))                          #data b'x89PNG...' <class 'bytes'>
       
       request.session["valid_code"]=valid_code               #将验证码放在session中

    return HttpResponse(data)

       2)点击登录,触发ajax提交事件

       前端代码

        

     $('#id_login').click(function () {
            $.ajax({
                url:'/login/',
                type:'post',
                data:{username:$('#id_username').val(),
                    password:$('#id_password').val(),
                    csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),
                    valid_code:$('#id_valid').val()
                    },
                success:function (data) {
                    if (data.status){
                        location.href='/index/'
                    }
                    else{
                        $('#id_login').next().text(data.error_msg);
                        setTimeout(function () {
                             $('#id_login').next().text('')
                        },1000)
                    }
                }
            })
        })

      后端代码

    def login(request):
    
        if request.is_ajax():
            username=request.POST.get('username')
            password=request.POST.get('password')
            valid_code=request.POST.get('valid_code')
            valid_CODE=request.session.get('valid_CODE')
            print(valid_CODE,valid_code)
            data={'status':None,'error_msg':None}
            if valid_code.lower()==valid_CODE.lower():
                user=auth.authenticate(username=username,password=password)        #验证有没有用户用auth.authenticate方法
                print(user)
                if user:
                    data['status']=1
                else:
                    data['status']=0
                    data['error_msg']='用户名或密码不存在!'
            else:
                data['status']=0
                data['error_msg']='验证码不正确!'
            return JsonResponse(data)
        return render(request,'login.html')

    day2 

      1 图像上传

      前端

      html代码

      PS label标签的妙用

        将<img>标签放在label标签内。这样在点击img标签的时候,就会触发label标签的事件,找到for='xx',在这里是找到<input type='file'>,会直接跳出其窗口。

                        <div class="form-group">
                <label for="id_avator" class="col-sm-2 control-label">头像<img style="margin-left: 80px" width="50px" height="50px" class="pull-left" id='id_img_avator' src="/static/default.png"></label> <div class="col-sm-10"> <input type="file" class="form-control" id="id_avator" placeholder="" style="display:None"> </div> </div>

      js代码

      PS   

        FileReader():读取文件,从文件中读取数据和保存在js变量中。

          参考知识网址:http://www.iunbug.com/archives/2012/06/04/220.html

      用FileReader():从文件中读取数据,存储到JS变量中

    <script>
        $('#id_avator').change(function () {            //上传图片,change时间。
            var file=$(this)[0].files[0];
            var reader=new FileReader();
            reader.readAsDataURL(file);
            reader.onload=function () {
                console.log(this);                          //FileReader {readyState: 2, result: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…oJDI5wRnHrmsm6kX3/OlSprsZj1Fwy/SevrSpUqeMLD//2Q==", error: null, onloadstart: null, onprogress: null, …}
                console.log(typeof this);                   //object
                $('#id_img_avator').attr('src',this.result)
            }
        })
    </script>

      test:测试 file,reader,this.result到底是什么东西。

    $('#id_avator').change(function () {
             var file=$(this)[0].files[0];
             console.log(file);
             console.log(typeof file);
             var reader=new FileReader();
             console.log(reader);
             console.log(typeof reader);
             reader.readAsDataURL(file);
             reader.onload=function () {
                 console.log(this.result);
                  $('#id_img_avator')[0].src=this.result}
    
         });

      输出:

    File(17989) {name: "th.jpg", lastModified: 1513684937519, lastModifiedDate: Tue Dec 19 2017 20:02:17 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 17989, …}
    (index):116 object
    (index):118 FileReader {readyState: 0, result: null, error: null, onloadstart: null, onprogress: null, …}
    (index):119 object
    (index):122 data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8...

      2 $.each()方法

      在js代码中

    success:function (data) {
                    if (data.user){
                        location.href='/index/'
                    }
                    else{
                        console.log(data.error_msg);
                        $('span').text('');
                        $('.form-control').removeClass('has-error');
                        $.each(data.error_msg,function (i,j) {                               
                            $('#id_'+i).next().addClass('pull-right').css('color','red').text(j[0]);
                            if (i=='__all__'){
                                $('#id_re_password').next().addClass('pull-right').css('color','red').html(j[0])
                            }
                        })
                    }
                }

      data.error_msg是正宗的字典。

      function(i,j) i 会取到key值,j会取到value值。value值是一个列表。

      if i=='__all__',判断全局钩子,密码与确认密码是否一致。

      

      3 

    $('#id_register').click(function () {
            var formdate=new FormData();
            formdate.append('username',$('#id_username').val());
            formdate.append('password',$('#id_password').val());
            formdate.append('re_password',$('#id_re_password').val());
            formdate.append('email',$('#id_email').val());
            formdate.append('valid_code',$('#id_valid_code').val());
            formdate.append('file_img',$('#id_avator')[0].files[0]);
            formdate.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
            $.ajax({
                url:'/register/',
                type:'post',
                processData:false,
                contentType:false,
                data:formdate,

      

      $('#id_avator')[0].files[0]是一个DOM对象,文件内容。

      需要将它发送给后端,用到了FormData类。

      后端代码

      接收FormData,都在request.POST中。

      经过is_valid()方法处理完后,数据都在cleaned_data和errors中。

      文件是一个特殊的存在,它的发送和取出都与其他不一样。

    def register(request):
        if request.is_ajax():
            formregister = FormRegister(request,request.POST)
            regResponse={'user':None,'error_msg':None}
            if formregister.is_valid():
                username=formregister.cleaned_data.get('username')
                password=formregister.cleaned_data.get('password')
                re_password=formregister.cleaned_data.get('re_password')
                email=formregister.cleaned_data.get('email')
                file_img=request.FILES.get('file_img')
                print('file_img',file_img,type(file_img))
                UserInfo.objects.create_user(username=username,password=password,email=email,avatar=file_img)
                regResponse['user']=1

      输出:

    file_img th.jpg <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>

      4 Form组件继承request

      forms.py 视为view.py 服务的

      在views.py中,视图函数

      def xxx(request):

        formreg=FormReg(request,request.POST):  

      在form.py中

      class FormReg(forms.Form)

        def__init__(request,*args,**kwargs)

          super().__init__(*args,**kwargs)

          self.request=request

        username=forms.Charfileld(..)

        ....

      这样 在form组件中,利用钩子可以去到保存在request.session中的验证码,可以在钩子里对验证码进行判定。

      解决了一个什么问题呢?

      form组件本身是单纯的帮助建立form表单的,除此之外好像并无别的高端用法。

      但form组件本质上是class类,类可以继承,在__init__的时候可以传参。

      so,form组件在views.py文件中实例化 的时候便可以传参,传各种需要的参数。

      将request传给form类,实例化的对象拿到request.session中的验证码。

      ajax提交,用户输入的验证码在request.POST中,经过is_valid(),在cleaned_data或者errors中。搞定!这样便可以验证了。

      高端的用法!

  • 相关阅读:
    .NET5都来了,你还不知道怎么部署到linux?最全部署方案,总有一款适合你
    一款基于.NET Core的认证授权解决方案-葫芦藤1.0开源啦
    开源项目葫芦藤:IdentityServer4的实现及其运用
    MySQL大表优化方案
    Sec-Fetch-*请求头,了解下?
    前端开发快速入门
    从零开始打造专属钉钉机器人
    打造钉钉事件分发平台之钉钉审批等事件处理
    React中的高阶组件
    浏览器本地存储方案
  • 原文地址:https://www.cnblogs.com/654321cc/p/8066525.html
Copyright © 2020-2023  润新知