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)
django文件上传和序列化的更多相关文章
- Django文件上传下载与富文本编辑框
django文件上传下载 上传 配置settings.py # 设定文件的访问路径,如:访问http://127.0.0.1:8000/media/就可以获取文件 MEDIA_URL = '/medi ...
- python_way day21 Django文件上传Form方式提交,原生Ajax提交字符处啊,Django文件上传之原生Ajax方式、jQuery Ajax方式、iframe方式,Django验证码,抽屉示例,
python_way day21 1.Django文件上传至Form方式 2.原生Ajax文件上传提交表单 使用原生Ajax好处:不依赖jquery,在发送一个很小的文件或者字符串的时候就可以用原生A ...
- django文件上传、图片验证码、抽屉数据库设计
1.Django文件上传之Form方式 settings.py, ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'd ...
- Django - 文件上传、Django组件 - 分页器(paginator)
一.文件上传准备知识 - Content-Type 1.请求头 - Content-Type Content-Type指的是请求体的编码类型,常见的类型共有3种: 1)application/x-ww ...
- django文件上传
-------------------上传图片-------------------1.model中定义属性类型为models.ImageField类型 pic=models.ImageField(u ...
- Python Web框架篇:Django文件上传
上传方式: - Form表单上传文件 - Ajax上传文件 - 基于form表单和iframe自己实现ajax请求 1,创建项目 2,settings配置(注册app01,static路径等等这些)及 ...
- Django文件上传(经典上传方式)
经典文件上传方式 创建URL from django.contrib import admin from django.urls import path from django.conf.urls i ...
- django——文件上传_分页_ajax_富文本_celery
上传文件 概述 当Django在处理文件上传时,文件的数据被存储在request.FILES属性中 FILES只有在请求的方法为POST且提交的form表单带有enctype="multip ...
- django 文件上传(阿里云oss)下载(支持大文件下载)
1.文件上传 Models 设计 class Upload_File(models.Model): image = models.FileField(upload_to='file/%Y/%m',de ...
随机推荐
- 苹果手机不支持click文字 需要添加 cursor:pointer 才能 识别可以点击
给一个div 绑定一个 click事件, 苹果手机会识别不了,必须添加一个 cursor:pointer 才能 识别可以点击.安卓正常识别.
- 【原】JAVA开发环境搭建
1.JDK下载并安装,以jdk-7u45-windows-i586.exe为例(注意JDK的安装和JRE的安装是分开的) 2.“我的电脑”右键属性,找到“高级系统设置”,找到“高级”tab下的“环境变 ...
- px-rem px转换为rem的工具
将px转换为rem的工具,github地址:https://github.com/finance-sh/px-rem 将px转换为rem的工具 怎样转换静态文件 安装: npm install px- ...
- 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器
× 目录 [1]id选择器 [2]元素选择器 [3]类选择器[4]通配选择器[5]群组选择器[6]后代选择器[7]兄弟选择器 前面的话 选择器是jQuery的根基,在jQuery中,对事件处理.遍历D ...
- 弹出层layer的使用
弹出层layer的使用 Intro layer是一款web弹层组件,致力于服务各个水平段的开发人员.layer官网:http://layer.layui.com/ layer侧重于用户灵活的自定义,为 ...
- NSDateFormatter 时间格式转换
NSString *strDate = @“Wed Apr ::”; NSDateFormatter *dateFomatter =[[NSDateFormatter alloc] init]; [d ...
- iOS通知的整理笔记
iOS通知用于高耦合界面的传值确实方便快捷. 需要实现模态弹出的视图控制器上,有一个视图控制器可以导航.这必定要将这个视图控制器的导航视图控制器naVC.view添加到模态弹出的视图控制器presen ...
- 安装redis以windows服务形式
安装redis以windows服务形式 安装redis以windows服务形式 redis windows windows 服务 以前跑redis,老是要开一个命令行窗口,一旦关闭,redis服务就挂 ...
- GDB调试命令小结
1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...
- 如何实现可动态调整隐藏header的listview
(转自:http://blog.sina.com.cn/s/blog_70b9730f01014sgm.html) 需求:根据某种需要,可能需要动态调整listview的页眉页脚,譬如将header作 ...