zoukankan      html  css  js  c++  java
  • day62

    登录功能

    登录功能前端验证码

    在urls中添加登录login路由,去views中定义login函数,新建一个login

    给前端页面添加图片验证码,设置图片的布局

    urls.py文件
    登录功能
        url(r'^login/',views.login,name='login'),
    图片验证码
    url(r'^get_code/',views.get_code,name='code'),
    
    
    views.py文件
    def login(request):
        if request.method =='POST':
            back_dic = {'code':1000,'msg':''}
            username = request.POST.get('username')
            password = request.POST.get('password')
            code = request.POST.get('code')
            if request.session.get('code').upper() == code.upper():
                user_obj = auth.authenticate(request,username=username,password=password)
                if user_obj:
                    auth.login(request,user_obj)
                    back_dic['msg'] = '登录成功'
                    back_dic['url'] = '/home/'
                else:
                    back_dic['code'] = 2000
                    back_dic['msg'] = '用户名或密码错误'
            else:
                back_dic['code'] = 3000
                back_dic['msg'] = '验证码错误'
            return JsonResponse(back_dic)
        return render(request,'login.html')
    

    views中写图片相关验证码

    def get_code(request):

    推导步骤1:直接发送后端存在的图片
    with open(r'avatar/444.jpg','rb') as f:
    	data = f.read()
    return HttpResponse(data)
    
    推导步骤2:利用pillow模块自动生成图片
    图片对象生成完毕
    利用文件操作先保存起来
    然后在利用文件操作将图片数据读取并发送
    
    推导步骤3:临时存储数据并且能够随时取出来的地方
    先生成一个io对象
    你就将对象看成是文件句柄即可
    存储数据
    读取数据
    获取二进制的数据
    
    推导步骤4:(最终推导)
    在图片上写字     下载.ttf的字体
    将生成好的图片对象交给ImageDraw
    生成一个画笔对象
    字体样式
    随机验证码  大小写英文数字   5位  每一位都可以是大写字母或小写字母或数字
    随机选取一个
    朝图片上写一个
    存储写的字
    
    # 图片验证码相关
    def get_code(request):
        # 推导步骤1:直接发送后端存在的图片
        # with open(r'avatar/444.jpg','rb') as f:
        #     data = f.read()
        # return HttpResponse(data)
        # 推导步骤2:利用pillow模块自动生成图片  pip3 install pillow
        # img_obj = Image.new('RGB',(360,35),get_random())  # 图片对象生成完毕
        # # 你得利用文件操作先保存起来
        # with open(r'xxx.png','wb') as f:
        #     img_obj.save(f,'png')
        # # 然后再利用文件操作将图片数据读取并发送
        # with open(r'xxx.png','rb') as f:
        #     data = f.read()
        # return HttpResponse(data)
        # 推导步骤3:临时存储数据并且能够随时取出的地方
        # img_obj = Image.new('RGB',(360,35),get_random())
        # # 先生成一个io对象
        # io_obj = BytesIO()  # 你就将对象看成是文件句柄即可
        # # 存储数据
        # img_obj.save(io_obj,'png')
        # # 读取数据
        # return HttpResponse(io_obj.getvalue())  # 获取二进制的数据
        # 推导步骤4(最终推导)  在图片上写字
        img_obj = Image.new('RGB',(360,35),get_random())
        # 将生成好的图片对象交给ImageDraw
        img_draw = ImageDraw.Draw(img_obj)  # 生成了一个画笔对象
        # 字体样式
        img_font = ImageFont.truetype('static/font/111.ttf',30)
    
        # 随机验证码    大小写英文加数字   五位 每一位都可以是大写字母或小写字母或数字
        code = ''
        for i in range(5):
            upper_str = chr(random.randint(65,90))
            lower_str = chr(random.randint(97,122))
            random_int = str(random.randint(0,9))
            # 随机选取一个
            tmp = random.choice([upper_str,lower_str,random_int])
            # 朝图片上写一个
            img_draw.text((i*60+60,0),tmp,get_random(),img_font)
            # 存储写的字
            code += tmp
        print(code)
        # 这个验证码后面其他视图函数可能要用到  找个地方存储一下 并且这个地方全局的视图函数都能访问
        request.session['code'] = code
        io_obj = BytesIO()
        img_obj.save(io_obj,'png')
        return HttpResponse(io_obj.getvalue())
    

    图片验证点击刷新

    这个验证码后面其他视图函数可能要用到   找个地方存储一下   并且这个地方全局的视图函数都能访问  存到session中
    request.session['code'] = code
    io_obj = BytesIO()
    img_obj.save(io_obj,'png')
    return HttpResponse(io_obj.getvalue())
    去前端添加点击事件  
    先拿到当前的src   给oldPath+='?'赋值 图片上的文字信息变动一次前端加一个?
    

    登录功能后端逻辑

    前端利用ajax发送post请求   拿到用户输入的用户名和密码
    后端先校验验证码是否正确  忽略大小写
    再校验用户名和密码是否正确
    保存用户登录状态
    利用auth模块校验数据  auth.login(request,user_obj) 
    就可以在任意的位置通过request.user获取到当前登录对象 
    并且request.user.is_authenticated()判断当前用户是否登录
    登录成功后返回home页面
    否则失败就用户名或密码错误
    再否则 验证码错误
    返回数据
    前端code如果等于1000就会跳转
    success:function (data) {
                    if(data.code == 1000){
                        // 跳转
                        window.location.href = data.url
                    }
                    
    
    
    
    views.py
    
    from django.shortcuts import render,HttpResponse,redirect,reverse
    from app01 import myform
    from app01 import models
    from django.http import JsonResponse
    from django.contrib import auth
    from django.contrib.auth.decorators import login_required
    
    # Create your views here.
    def register(request):
        form_obj = myform.MyRegForm()
        if request.method == 'POST':
            back_dic = {'code':1000,'msg':''}
            # 对用户提交的数据先进行校验 forms
            form_obj = myform.MyRegForm(request.POST)  # username password confirm_password email
            if form_obj.is_valid():
                clean_data = form_obj.cleaned_data  # {四个键值对}
                clean_data.pop('confirm_password')  # {username    password    email}
                file_obj = request.FILES.get('avatar')
                if file_obj:  # 一定要判断用户是否上传了文件
                    clean_data['avatar'] = file_obj  # {username  password email   avatar}
                models.Userinfo.objects.create_user(**clean_data)
                back_dic['msg'] = '注册成功'
                back_dic['url'] = '/login/'
            else:
                back_dic['code'] = 2000
                back_dic['msg'] = form_obj.errors
            return JsonResponse(back_dic)
        return render(request,'register.html',locals())
    
    
    def login(request):
        if request.method == "POST":
            back_dic = {'code':1000,'msg':''}
            username = request.POST.get('username')
            password = request.POST.get('password')
            code = request.POST.get('code')
            # 1.先校验验证码是否正确  忽略大写小
            if request.session.get('code').upper() == code.upper():
                # 2.在校验用户名和密码是否正确
                user_obj = auth.authenticate(request,username=username,password=password)
                if user_obj:
                    # 3.保存用户登录状态
                    auth.login(request,user_obj)  # 就可以在任意位置通过request.user获取到当前登录对象 并且 request.user.is_authenticated()判断当前用户是否登录
                    back_dic['msg'] = '登录成功'
                    back_dic['url'] = '/home/'
                else:
                    back_dic['code'] = 2000
                    back_dic['msg'] = '用户名或密码错误'
            else:
                back_dic['code'] = 3000
                back_dic['msg'] = '验证码错误'
            return JsonResponse(back_dic)
        return render(request,'login.html')
    
    
    from PIL import Image,ImageDraw,ImageFont
    import random
    from io import BytesIO,StringIO
    """
    内存管理器模块
    BytesIO  保存数据 并且在获取的时候 是以二进制的方式给你
    StringIO  保存数据 并且在获取的时候 是以字符串的方式给你
    """
    """
    Image       生成图片
    ImageDraw   在图片上写字
    ImageFont   控制字的字体样式
    """
    def get_random():
        return random.randint(0,255),random.randint(0,255),random.randint(0,255)
    
    
    
    # 图片验证码相关
    def get_code(request):
        # 推导步骤1:直接发送后端存在的图片
        # with open(r'avatar/444.jpg','rb') as f:
        #     data = f.read()
        # return HttpResponse(data)
        # 推导步骤2:利用pillow模块自动生成图片  pip3 install pillow
        # img_obj = Image.new('RGB',(360,35),get_random())  # 图片对象生成完毕
        # # 你得利用文件操作先保存起来
        # with open(r'xxx.png','wb') as f:
        #     img_obj.save(f,'png')
        # # 然后再利用文件操作将图片数据读取并发送
        # with open(r'xxx.png','rb') as f:
        #     data = f.read()
        # return HttpResponse(data)
        # 推导步骤3:临时存储数据并且能够随时取出的地方
        # img_obj = Image.new('RGB',(360,35),get_random())
        # # 先生成一个io对象
        # io_obj = BytesIO()  # 你就将对象看成是文件句柄即可
        # # 存储数据
        # img_obj.save(io_obj,'png')
        # # 读取数据
        # return HttpResponse(io_obj.getvalue())  # 获取二进制的数据
        # 推导步骤4(最终推导)  在图片上写字
        img_obj = Image.new('RGB',(360,35),get_random())
        # 将生成好的图片对象交给ImageDraw
        img_draw = ImageDraw.Draw(img_obj)  # 生成了一个画笔对象
        # 字体样式
        img_font = ImageFont.truetype('static/font/111.ttf',30)
    
        # 随机验证码    大小写英文加数字   五位 每一位都可以是大写字母或小写字母或数字
        code = ''
        for i in range(5):
            upper_str = chr(random.randint(65,90))
            lower_str = chr(random.randint(97,122))
            random_int = str(random.randint(0,9))
            # 随机选取一个
            tmp = random.choice([upper_str,lower_str,random_int])
            # 朝图片上写一个
            img_draw.text((i*60+60,0),tmp,get_random(),img_font)
            # 存储写的字
            code += tmp
        print(code)
        # 这个验证码后面其他视图函数可能要用到  找个地方存储一下 并且这个地方全局的视图函数都能访问
        request.session['code'] = code
        io_obj = BytesIO()
        img_obj.save(io_obj,'png')
        return HttpResponse(io_obj.getvalue())
    
    
    
    def home(request):
        return render(request,'home.html',locals())
    
    @login_required
    def logout(request):
        auth.logout(request)
        return redirect(reverse('home'))
    
    
    @login_required
    def set_password(request):
        if request.method == 'POST':
            old_password = request.POST.get('old_password')
            new_password = request.POST.get('new_password')
            confirm_password = request.POST.get('confirm_password')
            # 1 先判断旧密码是否正确
            is_right = request.user.check_password(old_password)
            if is_right:
                if new_password == confirm_password:
                    request.user.set_password(new_password)
                    request.user.save()
                    return redirect(reverse('login'))
                else:
                    return HttpResponse('两次密码不一致')
            else:
                return HttpResponse("原密码错误")
    

    内存管理模块

    BytesIO   保存数据  并且在获取的时候  是以二进制的方式给你
    StringIO  保存数据  并且在获取的时候  是字符串的方式给你
    
    Image      生成图片
    ImageDraw  在图片上写字
    ImageFont  控制字体样式
    

    首页搭建

    首页搭建
    url(r'^home/',views.home,name='home'),
    新建home页面,添加导航条,面板
    
    
    login.py
    
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        {% load static %}
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h2 class="text-center">登录页面</h2>
                <div class="form-group">
                    <label for="id_username">用户名</label>
                    <input type="text" id="id_username" name="username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_password">密码</label>
                    <input type="password" id="id_password" name="password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="id_code">验证码</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" name="code" id="id_code" class="form-control">
                        </div>
                        <div class="col-md-6">
                            <img src="/get_code/" alt="" width="360" height="35" id="id_img">
                        </div>
                    </div>
                </div>
                <input type="button" class="btn btn-primary" value="登录" id="id_submit">
                <span style="color: red;" id="id_error"></span>
            </div>
        </div>
    </div>
    
    <script>
        $('#id_img').click(function () {
            var oldPath = $(this).attr('src');
            $(this).attr('src',oldPath+='?')
        });
    
    
        $('#id_submit').click(function () {
            $.ajax({
                url:'',
                type:'post',
                data:{
                    'username':$('#id_username').val(),
                    'password':$('#id_password').val(),
                    'code':$('#id_code').val(),
                    'csrfmiddlewaretoken':'{{ csrf_token }}'
                },
                success:function (data) {
                    if(data.code == 1000){
                        // 跳转
                        window.location.href = data.url
                    }else{
                        $('#id_error').text(data.msg);
                        var oldPath = $('#id_img').attr('src');
                        $('#id_img').attr('src',oldPath+='?')
                    }
                }
            })
        })
    </script>
    </body>
    </html>
    

    导航条用户功能

    用户登录后才有一些操作功能,没有登录就登录注册

    在home页面中判断用户是否登录,利用模板语法

    修改密码,修改头像,后天管理,退出登录

    否则就登录注册

    在侧边栏添加面板

    跳出登录就在后端导入reverse

    在退出和设置密码上面加上装饰器

    添加弹框(模态框)

    修改密码
    url(r'^set_password/',views.set_password,name='set_pwd')
    

    给用户名添加disabled

    在form表单中 用户名 修改密码 原密码 新密码 确认密码

    添加两个按钮 取消 修改

    用户名是当前登录的用户名

    后端中views设置密码

    先判断旧密码是否正确

    两次密码是否一致

    否则两次密码不一致

    再否则原始密码错误

    新密码不一致

    判断新密码不能为空

    两次密码

    修改密码进入登录页面,修改成功即可登录

    今日考题

    1.简述企业项目开发流程

    需求分析:引导客户朝自己想要的方向提需求

    架构设计:架构师(框架,语言,数据库,缓存数据库,表设计,拆分功能,项目的报价(参与开发人员的个数 和开发工资,开发天数)

    分组开发:架构师组长会议:按模块功能拆分任务;小组会议:组长在拆分功能 每个组员写几个小功能;小组成员写代码:自己需要提前测试一下有没有bug

    交付测试:一些不是显而易见的bug

    运维上线:1.委托给你们公司帮忙上线帮忙维护 2.交给对方公司

    2.简述bbs表设计,有哪些重要字段,表与表之间什么关系

    用户表,个人站点表,文章标签表,文章分类表,文章表,文章点赞点踩表,文章评论表

    blog        一对一个人站点表
    tags        多对多文章标签表
    category    一对多文章标签表
    # 文章的点赞数  点踩数   评论数    数据库优化设计方案(*****)
    up_num
    down_num
    comment_num
    # 你只需要保证上面的三个普通字段跟对应的表中的数据同步更新即可
    article_id       一对多文章表			
    is_up			BooleanField	
    user_id          rticle_id
    content			TextField()
    create_time
    自关联 		  根评论子评论
    parent            跟自己所在的表外键关联  一对多
    id	user_id     article_id     parent_id
    

    3.简述bbs注册功能前后端业务逻辑

    只要是注册功能一般都有一定的校验规则
    		
    		我们利用forms组件 来完成注册的校验
    			用户名
    				label
    				error_messages
    					required
    					invalid
    				widget
    				validators
    			密码
    			确认密码
    			邮箱
    			
    			钩子函数
    				校验用户名是否已存在
    			
    				校验两次密码是否一致
    		
    		一旦你的项目特别庞大 需要用到很多forms组件 
    		那么你可以单独的将所有forms组件放到一个py文件中或者一个文件下
    		然后针对不同的功能开设不同的py文件
    			单独的py文件
    		
    			文件夹
    				1.py
    				2.py
    				3.py
    				4.py
    			
    	注册功能使用的是ajax做后端交互
    	但是我们用的了form标签
    		因为form标签有一个自动序列化普通键值对的功能
    		可以方便的将普通键值对循环添加到formdata对象中
    	
    	label标签在跟input有绑定关系的前提下
    	内部无论放什么对象 点击都能够是对应的input框聚焦
    	
    	img标签src属性可以放的值
    		1.图片的地址
    		2.图片的二进制数据
    		3.后端url   自动朝该url发送get请求
    	
    	实时展示用户选择的头像
    		利用内置对象fileReader
    			文件阅读器在读取文件的时候 是一个异步io操作
    			所以你在渲染img标签的时候一定要等待文件阅读器加载完毕之后再渲染
    			等待...加载完毕
    				onload
    				window.onload = function(){}
    				fileReader.onload = function(){}
    	发送ajax请求
    		1.ajax提交数据基本语法
    		2.ajax发送文件需要借助于内置对象formdata
    			ajax发送formdata对象
    			需要制定两个参数都为false
    				processData
    				contentType
    	后端正常的业务逻辑无需多说
    	
    	
    	一旦报错之后前端如何对应的渲染相应的信息
    		1.你需要研究form组件渲染的input框的id值的特点
    			id_字段名
    		2.你又发现返回的报错信息 键就是一个个的字段名
    			自己手动拼接处input框的id值
    			然后利用DOM操作 来操作span标签以及div标签
    	
    	最后为了功能的健壮性
    		给所有的input设置获取焦点事件
    			自动移除报错信息和报错的样式
    

    4.简述编译型语言和解释型语言?你所知道的编译型语言和解释型语言有什么?

    编译型语言  ->  机器语言                               
    解释型语言  ->   解释成中间语言 ->机器语言
    
    编译型语言:C、C++、Pascal/Object Pascal(Delphi);
    解释型语言:Python、JavaScript、Shell、Ruby、MATLAB等
    
    
    
    java是编译型语言还是解释型语言?
    java语言应是编译性-解释性语言,因为其同时具备编译性和解释性两种特性;
    java文件先编译成与平台无关的.class的字节码文件,然后.class的字节码文件既可以在Windows平台上的java虚拟机(JVM)上进行解释运行,也可以在Linux平台上的JVM上解释运行;
    而JVM的翻译过程是解释性的,
    JVM从.class的字节码文件中读出一条指令,翻译一条指令,然后执行一条指令,这个过程就称为java的解释执行;
    
    fileReader.onload = function(){}  解决异步文件读取造成的问题
    
  • 相关阅读:
    各种加密解密函数(URL加密解密、sha1加密解密、des加密解密)
    php实现和c#一致的DES加密解密
    使用phpQuery轻松采集网页内容
    PHP 类与对象 全解析(三)
    PHP 类与对象 全解析( 二)
    PHP 类与对象 全解析( 一)
    iconv 中文截断问题的解决方法
    jQuery插件开发全解析
    jQuery ajax
    360手机新品牌5月6日公布 周鸿祎席地而坐谈AK47
  • 原文地址:https://www.cnblogs.com/gfhh/p/12013498.html
Copyright © 2011-2022 走看看