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的基本语法及一些设置

    rm -r note.txt //delete网络配置进入 vi /etc/sysconfig/network-scripts/ifcfg-teh0修改配置DEVICE=eth0BOOTPROTO=d ...

  2. Sencha ExtJS 6 Widget Grid 入门

    最近由于业务需要,研究了一下Sencha ExtJS 6 ,虽然UI和性能上据相关资料说都有提升,但是用起来确实不太顺手,而且用Sencha cmd工具进行测试和发布,很多内部细节都是隐藏的,出了问题 ...

  3. hello,world!

    我是马燕,在2017即将来临之际,我希望自己,在新的一年里,能开开心心,健健康康,家人平平安安! 我会努力工作,努力学习,离自己的理想越来越接近. 以后我会将我的所学所得写在这里,供未来的自己随时查看 ...

  4. 浅析CSS中的BFC和IFC

    1. 为什么会有BFC和IFC 首先要先了解两个概念:Box和formatting context: Box:CSS渲染的时候是以Box作为渲染的基本单位.Box的类型由元素的类型和display属性 ...

  5. 压缩html

    最近研究程序的优化,压缩html可以减小html的体积,有利于提高页面的相应速度.在webform的basepage中添加如下代码: /// <summary> /// 重写Render方 ...

  6. div 模拟<select>事件

    IE7 下,不能够自定义<select>/<option>的样式,所以为了方便起见,用div可以进行模拟 <!doctype html> <html> ...

  7. 使用Kotlin对ViewGroup的视图进行函数使操作

    原文标题:Functional operations over Views in ViewGroup using Kotlin 原文链接:http://antonioleiva.com/functio ...

  8. 【转】漫谈iOS程序的证书和签名机制

    转自:漫谈iOS程序的证书和签名机制 接触iOS开发半年,曾经也被这个主题坑的摸不着头脑,也在淘宝上买过企业证书签名这些服务,有大神都做了一个全自动的发布打包(不过此大神现在不卖企业证书了),甚是羡慕 ...

  9. 【代码笔记】iOS-正方形转换

    一,工程图. 二,代码. RootViewControlle.m //点击任何处,页面翻转 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEven ...

  10. 安卓开发树形控件之ExpandableListView(一)

    这个例子非常简单,简单到一个初学者都能随便开发出来,今天的目的仅仅只是为了将效果实现出来,如果想深入这里有几篇非常不错的博客: Android 之ExpandableListView几个特殊的属性 h ...