python运维开发(二十一)----文件上传和验证码+session
内容目录:
文件上传
验证码+session
文件和图片的上传功能
- HTML Form表单提交,实例展示
views 代码
HTML
 - ajax提交
 
- 原生ajax提交,XMLHttpRequest方式上传
 - jQuery Ajax提交
 
两种提交方式对比
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .img{
            width: 300px;
            height: 300px;
        }
    </style>
</head>
<body>
    <iframe id="my_iframe"  name="my_iframe"  style="display: none" src=""></iframe>
    <form id="fo" method="POST" action="/upload/" enctype="multipart/form-data">
        <input type="text" id="user" name="user" />
        <input type="file" id="img" name="img" onchange="uploadFile3();" />
        <input type="submit" />
    </form>
    <div id="container">
    </div>
    <a onclick="uploadFile1();" >XMLHttpRequest上传</a>
    <a onclick="uploadFile2();" >jQueryAjax上传</a>
    <a onclick="uploadFile3();" >测试Iframe</a>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function uploadFile1(){
            // 创建表单对象
            var form = new FormData();
            // 在表单对象中添加:user: 用户输入的用户名
            form.append('user',document.getElementById('user').value);
            // 在表单对象中添加:img: 文件对象
            var fileObj = document.getElementById("img").files[0];
            form.append("img", fileObj);
            var xhr = new XMLHttpRequest();
            // 回调函数,当Ajax请求状态变化时,自动触发
            xhr.onreadystatechange = function(){
                // xhr.readyState=4 表示,客户端已经将服务器端响应的内容全部获取完毕
                if(xhr.readyState == 4){
                    //  xhr.responseText 获取服务器端响应的文本内容,即: views中 return HttpResponse中的内容
                    var data = xhr.responseText;
                    console.log(data);
                }
            };
            // 创建异步连接
            xhr.open("post", '/upload/', true);
            // 发送请求,将form中的数据发送到服务器端
            xhr.send(form);
        }
        function uploadFile2(){
            // jQuery对象和dom对象
            var fileObj = $("#img")[0].files[0];
            var form = new FormData();
            form.append("img", fileObj);
            form.append("user", 'alex');
            $.ajax({
                type:'POST',
                url: '/upload/',
                data: form,// # {'k1': ;'v1'}  >  send('k1=v1')
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success: function(arg){
                    console.log(arg);
                }
            })
        }
        function uploadFile3(){
            $('#container').find('img').remove();
            document.getElementById('my_iframe').onload = callback;
            document.getElementById('fo').target = 'my_iframe';
            document.getElementById('fo').submit();
        }
        function callback(){
            var text = $('#my_iframe').contents().find('body').text();
            var json_data = JSON.parse(text);
            console.log(json_data);
            if(json_data.status){
                // 已经上传成功
                // 预览,创建image标签,src指向刚上传的静态文件路径
                var tag = document.createElement('img');
                tag.src = "/" + json_data.data;
                tag.className = 'img';
                $('#container').append(tag);
            }else{
                alert(json_data.error);
            }
        }
    </script>
</body>
</html>
upload.html
from django.shortcuts import render,HttpResponse
import os
import json
# Create your views here.
def upload(request):
    if request.method == 'POST':
        ret = {'status': False, 'data': None, 'error': None}
        try:
            user = request.POST.get('user')
            # img = request.POST.get('img')
            img = request.FILES.get('img')
            print(type(img))
            from django.core.files.uploadedfile import InMemoryUploadedFile
            file_path = os.path.join('static', img.name)
            f = open(file_path,'wb')
            for chunk in img.chunks():
                f.write(chunk)
            f.close()
            ret['status'] = True
            ret['data'] = file_path
        except Exception as e:
            ret['error'] = str(e)
        return HttpResponse(json.dumps(ret))
    return render(request, 'upload.html')
def ajax(request):
    import time
    crruent_time = time.time()
    return render(request, 'ajax.html',{'crruent_time': crruent_time})
def xhr_ajax(request):
    print(request.GET)
    print(request.POST)
    return HttpResponse('ok')
views.py
验证码+session
验证码主图片需要导入check_code和一个Monaco.ttf 字体,字体文件放到项目的根目录下
#!/usr/bin/env python
#coding:utf-8
import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
_letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper()  # 大写字母
_numbers = ''.join(map(str, range(3, 10)))  # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers))
def create_validate_code(size=(120, 30),
                         chars=init_chars,
                         img_type="GIF",
                         mode="RGB",
                         bg_color=(255, 255, 255),
                         fg_color=(0, 0, 255),
                         font_size=18,
                         font_type="Monaco.ttf",
                         length=4,
                         draw_lines=True,
                         n_line=(1, 2),
                         draw_points=True,
                         point_chance = 2):
    '''
    @todo: 生成验证码图片
    @param size: 图片的大小,格式(宽,高),默认为(120, 30)
    @param chars: 允许的字符集合,格式字符串
    @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
    @param mode: 图片模式,默认为RGB
    @param bg_color: 背景颜色,默认为白色
    @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
    @param font_size: 验证码字体大小
    @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
    @param length: 验证码字符个数
    @param draw_lines: 是否划干扰线
    @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
    @param draw_points: 是否画干扰点
    @param point_chance: 干扰点出现的概率,大小范围[0, 100]
    @return: [0]: PIL Image实例
    @return: [1]: 验证码图片中的字符串
    '''
    width, height = size # 宽, 高
    img = Image.new(mode, size, bg_color) # 创建图形
    draw = ImageDraw.Draw(img) # 创建画笔
    def get_chars():
        '''生成给定长度的字符串,返回列表格式'''
        return random.sample(chars, length)
    def create_lines():
        '''绘制干扰线'''
        line_num = random.randint(*n_line) # 干扰线条数
        for i in range(line_num):
            # 起始点
            begin = (random.randint(0, size[0]), random.randint(0, size[1]))
            #结束点
            end = (random.randint(0, size[0]), random.randint(0, size[1]))
            draw.line([begin, end], fill=(0, 0, 0))
    def create_points():
        '''绘制干扰点'''
        chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]
        for w in range(width):
            for h in range(height):
                tmp = random.randint(0, 100)
                if tmp > 100 - chance:
                    draw.point((w, h), fill=(0, 0, 0))
    def create_strs():
        '''绘制验证码字符'''
        c_chars = get_chars()
        strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开
        font = ImageFont.truetype(font_type, font_size)
        font_width, font_height = font.getsize(strs)
        draw.text(((width - font_width) / 3, (height - font_height) / 3),
                    strs, font=font, fill=fg_color)
        return ''.join(c_chars)
    if draw_lines:
        create_lines()
    if draw_points:
        create_points()
    strs = create_strs()
    # 图形扭曲参数
    params = [1 - float(random.randint(1, 2)) / 100,
              0,
              0,
              0,
              1 - float(random.randint(1, 10)) / 100,
              float(random.randint(1, 2)) / 500,
              0.001,
              float(random.randint(1, 2)) / 500
              ]
    img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲
    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大)
    return img, strs
check_code.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/login/" method="POST">
        <input type="text" name="username" />
        <input type="text" name="pwd" />
        <input type="text" name="check_code" />
        <img src="/check_code/" onclick="ChangeCode(this);">
        <input type="submit" />
    </form>
    <script>
        function ChangeCode(ths){
            ths.src = ths.src + '?';
        }
    </script>
</body>
</html>
login.html
def check_code(request):
    import io
    from backend import check_code as CheckCode
    stream = io.BytesIO()
    # img图片对象,code在图像中写的内容
    img, code = CheckCode.create_validate_code()
    img.save(stream, "png")
    request.session["CheckCode"] = code
    return HttpResponse(stream.getvalue())
    # 代码:生成一张图片,在图片中写文件
    # request.session['CheckCode'] =  图片上的内容
    # 自动生成图片,并且将图片中的文字保存在session中
    # 将图片内容返回给用户
def login(request):
    if request.method == 'POST':
        input_code = request.POST.get('check_code')
        print(input_code.upper(),request.session['CheckCode'].upper())
    return render(request, 'login.html')
Views.py
引用url:
http://www.cnblogs.com/wupeiqi/articles/5703697.html
python运维开发(二十一)----文件上传和验证码+session的更多相关文章
- python运维开发(二十)----models操作、中间件、缓存、信号、分页
		
内容目录 select Form标签数据库操作 models操作F/Q models多对多表操作 Django中间件 缓存 信号 分页 select Form标签补充 在上一节中我们可以知道Form标 ...
 - python运维开发(二十二)---JSONP、瀑布流、组合搜索、多级评论、tornado框架简介
		
内容目录: JSONP应用 瀑布流布局 组合搜索 多级评论 tornado框架简介 JSONP应用 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. ...
 - python运维开发(七)----面向对象(上)
		
内容目录: 面向对象应用场景 类和对象的创建 类中的__init__构造方法 self理解 面向对象的三大特性:封装.继承.多态 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装 ...
 - python运维开发(二十五)---cmdb开发
		
内容目录: 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infr ...
 - python运维开发(二十四)----crm权限管理系统
		
内容目录: 数据库设计 easyUI的使用 数据库设计 权限表Perssion 角色表Role 权限和角色关系表RoleToPermission 用户表UserInfo 用户和角色关系表UserInf ...
 - python运维开发(二十三)---tornado框架
		
内容目录: 路由系统 模板引擎 cookie 加密cookie 自定义api 自定义session 自定义form表单验证 异步非阻塞 web聊天室实例 路由系统 路由系统其实就是 url 和 类 的 ...
 - Python运维开发基础09-函数基础【转】
		
上节作业回顾 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 实现简单的shell命令sed的替换功能 import ...
 - Python运维开发基础08-文件基础【转】
		
一,文件的其他打开模式 "+"表示可以同时读写某个文件: r+,可读写文件(可读:可写:可追加) w+,写读(不常用) a+,同a(不常用 "U"表示在读取时, ...
 - Python运维开发基础07-文件基础【转】
		
一,文件的基础操作 对文件操作的流程 [x] :打开文件,得到文件句柄并赋值给一个变量 [x] :通过句柄对文件进行操作 [x] :关闭文件 创建初始操作模板文件 [root@localhost sc ...
 
随机推荐
- 查看Linux系统相关版本信息
			
1.“uname -a” 查看电脑以及操作系统的相关信息 2.“cat /proc/version” 查看运行的内核版本 3."cat /etc/redhat-release", ...
 - javascript第二课练习
			
<script type="text/javascript"> window.onload=function() //网页全部加载完后执行 { va ...
 - Hdu1094
			
#include <stdio.h> int main() { ; while(scanf("%d",&n)!=EOF){ ;i<n;i++){ scan ...
 - iOS学习之界面间传值
			
/** * 界面间传值步骤 1.界面传值第一种场场景:从前往后传值. 秘诀:属性传值.(葵花宝典). 招式:(1).在后一个界面定义属性,属性的类型和传出数据类型一致. (2).在进入下一界面之前, ...
 - CocosCode IDE 打包APK失败的原因
			
因为在lua目录下应用了git版本控制,导致打包的时候,复制(移动).git里面的文失败.从而第一次能打包成功,第二次之后就会失败.提示 os.move()失败.对应framworks/runtime ...
 - 《Programming WPF》翻译 第9章 3.自定义功能
			
原文:<Programming WPF>翻译 第9章 3.自定义功能 一旦你挑选好一个基类,你将要为你的控件设计一个API.大部分WPF元素提供属性暴露了多数功能,事件,命令,因为他们从框 ...
 - 《Programming WPF》翻译 第8章 3.Storyboard
			
原文:<Programming WPF>翻译 第8章 3.Storyboard Storyboard是动画的集合.如果你使用了标记,所有的动画必须要被定义在一个Storyboard中.(在 ...
 - Quartus DSE 初步应用
			
介绍 Design Space Explorer (DSE) is a program that automates the process of finding the optimal collec ...
 - 【HDU2795】Billboard(线段树)
			
大意:给一个h*w的格子,然后给出多个1*w的板子往格子里面填,如果有空间尽量往上一行填满,输出行数,无法填补,则输出-1: 可以使用线段树转化问题,将每一排的格子数目放到每一个叶子节点上,然后每有一 ...
 - 【实用技术】DreamWeaver常用快捷键
			
文件菜单 新建文档 Ctrl+N 打开一个HTML文件 Ctrl+O 或者将文件从[文件管理器]或[站点]窗口拖动到[文档]窗口中 在框架中打开 Ctrl+Shift+O 关闭 Ctrl+W 保存 C ...