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‘, ‘123‘);
            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)
时间: 2024-12-17 17:26:08

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

django文件上传

django文件上传 -------------------上传图片-------------------1.model中定义属性类型为models.ImageField类型pic=models.ImageField(upload_to='images/upload/') 2.如果属性类型为ImageField需要安装包Pilowpip install Pillow==3.4.1 3.图片存储路径1.在项目根目录下创建static文件夹 2.图片上传后,会被保存到"/static/images/

Django文件上传机制用法详解(转)

Django文件上传机制用法详解 http://www.jbxue.com/article/24283.html 分享下Django文件上传机制的用法,包括基本上传文件的原理,以及如何处理上传文件的方法,需要的朋友参考下. 当Django处理上传一个文件时,文件数据被放在request.FILES中. 这个文档解释文件怎么样被存储在磁盘上或者内存中,怎样定制默认的行为. 一,基本文件上传考虑一个包含FileField的简单的表单: 复制代码 代码示例: from  django  import 

Django文件上传实例

近日在用Django框架开发过程中遇到上传用户头像问题,经多方搜索资料,终于解决问题! 1.首先,在html模版中添加类似下面的代码 1 2 3 4 5 <form enctype="multipart/form-data" method="POST" action="/view/process/upload/file">     {% csrf_token %}     <input type="file"

Django——文件上传

Django在处理文件上传时,文件数据被打包封装在request.FILES中. 一.简单上传 首先,在模型中创建表格,它必须包含一个FileField: # models.py from django import forms class UploadFile(forms.Form): file = forms.FileField() 处理这个表单的视图将在request.FILES中收到文件数据,可以用request.FILES['file']来获取上传文件的具体数据,其中的键值‘file’

django文件上传下载

views: def mgmt_files(request): #列出树形目录,上传文件页面 if request.method == 'POST': path_root = "D:\\py\\ITFiles" #上传文件的主目录 myFile =request.FILES.get("file", None) # 获取上传的文件,如果没有文件,则默认为None if not myFile: dstatus = "请选择需要上传的文件!" else

django文件上传的几种方式

方式一:通过form表单中,html input 标签的“file”完成 1 2 3 4 5 6 # 前端代码uoload.html     <form method="post" action="/upload/" enctype="multipart/form-data">         <input id="user" type="text" name="user&quo

django 学习-14 Django文件上传 (Admin后台)

1.这种上传方式是用admin后台完成的,用数据库和model做 vim settings.py MEDIA_ROOT = '/headImg/'                                   文件保存在路径(还有后续) #   'django.middleware.csrf.CsrfViewMiddleware',            禁掉这个,跨站不会出问题 'django.contrib.admin',                                

Django - 文件上传

1 修改project的settings.py,添加 MEDIA_URL = '/media/' #这个是浏览器访问的地址, 例如:http://127.0.0.1:8000/media/covers/21.png MEDIA_ROOT = os.path.join(BASE_DIR, 'media') #这个是文件在服务器上保存的根目录,这里为proje根目录下的media目录,里面有covers/21.png,可以通过上面的方式访问该文件 2 修改project的urls.py文件,添加 .

django中处理文件上传文件

1 template模版文件uploadfile.html 特别注意的是,只有当request方法是POST,且发送request的<form>有属性enctype="multipart/form-data"时,request.FILES中包含文件数据,否则request.FILES为空. <form method="post" action="" enctype="multipart/form-data"