django文件上传和序列化

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)
上一篇:SSE图像算法优化系列二十九:基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一)


下一篇:转:Maven 标签