Django - upload de arquivo e de download

formulário de upload forma

 

Não tantos coisa, olhada em um exemplo:
código de front-end é importante.

<div>
    <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} <input type="file" name="f1"> <input type="text" name="user"> <input type="submit" value="提交"> </form> </div> 

Em geral, quando um normal de envio de formulário formulário, cabeçalho do pedido CONTENT_TYPE: application/x-www-form-urlencoded, e depois os dados são transmitidos na forma de pares chave-valor, o servidor a partir request.POSTdo valor, não há dúvida, e CONTENT_TYPE: application/x-www-form-urlencodedeste tipo de codificação para a maioria dos casos, tudo muito bom.

E dizer que o uso de formulário formulário para fazer upload de um arquivo, você tem que dizer algumas palavras para cima.
Na primeira, o protocolo http não é arquivos aspectos funcionais de upload até RFC1867 adicionar esta funcionalidade ao protocolo http. RFC1867 definido no curso de  formetiqueta  method deve ser  POST, enctype = "multipart/form-data" também <input type = "file">.
Então, quando se utiliza a forma formulário para fazer upload de documentos, solicitação de cabeçalho content_typeé multipart/form-dataessa forma, por isso precisamos adicionar um formulário tag enctype="multipart/form-dataatributos para identificação.
Se você pode imprimir cabeçalho de solicitação de upload de arquivos, você vai encontrar CONTENT_TYPEé este content_type:multipart/form-data; boundary=----WebKitFormBoundarylZZyJUkrgm6h34DU, que boundary=----WebKitFormBoundarylZZyJUkrgm6h34DUo que é?
Em multipart/form-data trás boundarye uma sequência de caracteres, este é o delimitador, uma pilha atrás da cadeia gerada aleatoriamente, a fim de prevenir a ocorrência delimitador servidor de upload de arquivo não pode identificar corretamente o início do arquivo. Isso delimitador e dim-lo?
Para a solicitação post para fazer upload de um arquivo, nós não utilizar o protocolo http original, para multipart / pedido formulário de dados é baseado no pedido http originais método post vem, então diz-se que a diferença entre esta nova forma de publicar o pedido:

  1. Solicitar uma cabeça diferente, um pedido de upload de arquivos contentType = multipart/form-dataé necessário, mas post não é, afinal de contas, não são apenas fazer upload de arquivos postar ~.
  2. Diferente corpo da solicitação, é diferente aqui refere-se ao ex-(pedido de envio) deve ser utilizado entre cada delimitador de campo para separar a transmissão de conteúdo, tais como conteúdo e arquivos de texto precisa espaçadas, caso contrário, o servidor não há nenhuma maneira o arquivo de resolução normal, o que obviamente não é pós delimitador diretamente key:valuetransmitida na forma dele.

Claro, a curva em torno de algumas palavras não podem explicar claramente, sabemos como usar na linha.
visualizações olhar vista de um processo:

from django.shortcuts import render, redirect, HttpResponse
from django.db import transaction
def import_case(request, pk): """ 导入Excel数据,pk是所属项目的pk """ if request.method == 'POST': try: with transaction.atomic(): # 事物 # project_pk = request.POST.get("project_pk") # 数据库使用字段 excel = request.FILES.get('file_obj') book = xlrd.open_workbook(filename=None, file_contents=excel.read()) sheet = book.sheet_by_index(0) title = sheet.row_values(0) for row in range(1, sheet.nrows): print(sheet.row_values(row)) # 这里取出来每行的数据,就可以写入到数据库了 return HttpResponse('OK') except Exception as e: print(e) return render(request, 'import_case.html', {"project_pk": pk, "error": "上传文件类型有误,只支持 xls 和 xlsx 格式的 Excel文档"}) return render(request, 'import_case.html', {"project_pk": pk, "error": ""}) 

upload de arquivos ajax

 

A extremidade dianteira do arquivo:

<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- ajax上传文件开始 --> <div> {% csrf_token %} <input type="file" id="ajaxFile"> <button id="ajaxBtn">上传</button> </div> <!-- ajax上传文件结束 --> </body> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script> console.log($("[name='csrfmiddlewaretoken']").val()); $("#ajaxBtn").click(function () { // 首先,实例化一个formdata对象 var formData = new FormData(); // 然后使用formdata的append来添加数据,即获取文件对象 // var file_obj = $("#ajaxFile")[0].files[0]; // 使用jQuery获取文件对象 var file_obj = document.getElementById('ajaxFile').files[0]; // 使用dom也行 formData.append('f1', file_obj ); // 处理csrftoken formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val()); // 也可以将其他的数据,以键值对的形式,添加到formData中 formData.append('user','张开'); $.ajax({ url: "/upload/", type: "POST", data: formData, processData:false, // contentType:false, success:function (dataMsg) { console.log(dataMsg); } }) }) </script> </html> 

Ajax conjunto, a fim de evitar o contentType falsa pedido cabeça JQuery content_typeopera, perdendo assim delimitador, o servidor de arquivos não podem resolver adequadamente.
No método utilizando jQuery $ .ajax () quando o parâmetro ProcessData padrão para verdadeiro (que é um jQuery único), o padrão será o caso da sequência de dados transmitidos para a adaptação / x-www-forma aplicação tipo de conteúdo padrão -urlencoded
tempo se você quiser não quiser enviar informações para a necessidade de defini-lo manualmente para falso.
Vamos olhar o back-end views.pycomo lidar com:

import xlrd
from django.shortcuts import render
from django.http import JsonResponse def upload(request): if request.is_ajax(): # print(request.META['CONTENT_TYPE']) # multipart/form-data; boundary=----WebKitFormBoundaryuXDgAwSKKIGnITam # print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['mx1EBTtsOb0k96TUUW8XKbCGvK0Co3S6ZMlLvOuZOKAlO9nfhf6zol0V8KxRxbwT'], 'user': ['张开']}> # print(request.FILES) # <MultiValueDict: {'f1': [<InMemoryUploadedFile: 接口测试示例.xlsx (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)>]}> f1 = request.FILES.get('f1') print(f1) # 接口测试示例.xlsx book = xlrd.open_workbook(filename=None, file_contents=f1.read()) sheet = book.sheet_by_index(0) print(sheet.row_values(1)) # ['cnodejs项目', 'get /topics 主题首页', 'https://cnodejs.org/api/v1/topics', 'get', '', '{"success":true}'] return JsonResponse({"message": "upload successful"}) else: return render(request, 'upload.html') 

OK, digamos que não é bom, seca estaria terminado.

baixar

 

Use StreamingHttpResponse

 

vê no código principal:

from django.http import StreamingHttpResponse
def download(request): file=open('crm/models.py','rb') response =StreamingHttpResponse(file) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="models.py"' return response 

Use FileResponse

 

vê no código principal:

from django.http import FileResponse
def download(request): file=open('crm/models.py','rb') response =FileResponse(file) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="models.py"' return response 

Nome de arquivo não pode resolver os problemas em chinês

 

Se você é cuidadoso para tentar, você vai encontrar duas maneiras para baixar o acima filenamenão pode conter chinês, então como resolvê-lo? Para olhar para baixo!

from django.http import FileResponse
from django.utils.encoding import escape_uri_path   # 导入这个家伙 def download(request): file=open('crm/models.py','rb') response =FileResponse(file) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="{}.py"'.format(escape_uri_path("我是中文啦")) return response 

Não está resolvido! Perfeito! !

formulário de upload forma

 

Não tantos coisa, olhada em um exemplo:
código de front-end é importante.

<div>
    <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} <input type="file" name="f1"> <input type="text" name="user"> <input type="submit" value="提交"> </form> </div> 

Em geral, quando um normal de envio de formulário formulário, cabeçalho do pedido CONTENT_TYPE: application/x-www-form-urlencoded, e depois os dados são transmitidos na forma de pares chave-valor, o servidor a partir request.POSTdo valor, não há dúvida, e CONTENT_TYPE: application/x-www-form-urlencodedeste tipo de codificação para a maioria dos casos, tudo muito bom.

E dizer que o uso de formulário formulário para fazer upload de um arquivo, você tem que dizer algumas palavras para cima.
Na primeira, o protocolo http não é arquivos aspectos funcionais de upload até RFC1867 adicionar esta funcionalidade ao protocolo http. RFC1867 definido no curso de  formetiqueta  method deve ser  POST, enctype = "multipart/form-data" também <input type = "file">.
Então, quando se utiliza a forma formulário para fazer upload de documentos, solicitação de cabeçalho content_typeé multipart/form-dataessa forma, por isso precisamos adicionar um formulário tag enctype="multipart/form-dataatributos para identificação.
Se você pode imprimir cabeçalho de solicitação de upload de arquivos, você vai encontrar CONTENT_TYPEé este content_type:multipart/form-data; boundary=----WebKitFormBoundarylZZyJUkrgm6h34DU, que boundary=----WebKitFormBoundarylZZyJUkrgm6h34DUo que é?
Em multipart/form-data trás boundarye uma sequência de caracteres, este é o delimitador, uma pilha atrás da cadeia gerada aleatoriamente, a fim de prevenir a ocorrência delimitador servidor de upload de arquivo não pode identificar corretamente o início do arquivo. Isso delimitador e dim-lo?
Para a solicitação post para fazer upload de um arquivo, nós não utilizar o protocolo http original, para multipart / pedido formulário de dados é baseado no pedido http originais método post vem, então diz-se que a diferença entre esta nova forma de publicar o pedido:

  1. Solicitar uma cabeça diferente, um pedido de upload de arquivos contentType = multipart/form-dataé necessário, mas post não é, afinal de contas, não são apenas fazer upload de arquivos postar ~.
  2. Diferente corpo da solicitação, é diferente aqui refere-se ao ex-(pedido de envio) deve ser utilizado entre cada delimitador de campo para separar a transmissão de conteúdo, tais como conteúdo e arquivos de texto precisa espaçadas, caso contrário, o servidor não há nenhuma maneira o arquivo de resolução normal, o que obviamente não é pós delimitador diretamente key:valuetransmitida na forma dele.

Claro, a curva em torno de algumas palavras não podem explicar claramente, sabemos como usar na linha.
visualizações olhar vista de um processo:

from django.shortcuts import render, redirect, HttpResponse
from django.db import transaction
def import_case(request, pk): """ 导入Excel数据,pk是所属项目的pk """ if request.method == 'POST': try: with transaction.atomic(): # 事物 # project_pk = request.POST.get("project_pk") # 数据库使用字段 excel = request.FILES.get('file_obj') book = xlrd.open_workbook(filename=None, file_contents=excel.read()) sheet = book.sheet_by_index(0) title = sheet.row_values(0) for row in range(1, sheet.nrows): print(sheet.row_values(row)) # 这里取出来每行的数据,就可以写入到数据库了 return HttpResponse('OK') except Exception as e: print(e) return render(request, 'import_case.html', {"project_pk": pk, "error": "上传文件类型有误,只支持 xls 和 xlsx 格式的 Excel文档"}) return render(request, 'import_case.html', {"project_pk": pk, "error": ""}) 

upload de arquivos ajax

 

A extremidade dianteira do arquivo:

<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- ajax上传文件开始 --> <div> {% csrf_token %} <input type="file" id="ajaxFile"> <button id="ajaxBtn">上传</button> </div> <!-- ajax上传文件结束 --> </body> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script> console.log($("[name='csrfmiddlewaretoken']").val()); $("#ajaxBtn").click(function () { // 首先,实例化一个formdata对象 var formData = new FormData(); // 然后使用formdata的append来添加数据,即获取文件对象 // var file_obj = $("#ajaxFile")[0].files[0]; // 使用jQuery获取文件对象 var file_obj = document.getElementById('ajaxFile').files[0]; // 使用dom也行 formData.append('f1', file_obj ); // 处理csrftoken formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val()); // 也可以将其他的数据,以键值对的形式,添加到formData中 formData.append('user','张开'); $.ajax({ url: "/upload/", type: "POST", data: formData, processData:false, // contentType:false, success:function (dataMsg) { console.log(dataMsg); } }) }) </script> </html> 

Ajax conjunto, a fim de evitar o contentType falsa pedido cabeça JQuery content_typeopera, perdendo assim delimitador, o servidor de arquivos não podem resolver adequadamente.
No método utilizando jQuery $ .ajax () quando o parâmetro ProcessData padrão para verdadeiro (que é um jQuery único), o padrão será o caso da sequência de dados transmitidos para a adaptação / x-www-forma aplicação tipo de conteúdo padrão -urlencoded
tempo se você quiser não quiser enviar informações para a necessidade de defini-lo manualmente para falso.
Vamos olhar o back-end views.pycomo lidar com:

import xlrd
from django.shortcuts import render
from django.http import JsonResponse def upload(request): if request.is_ajax(): # print(request.META['CONTENT_TYPE']) # multipart/form-data; boundary=----WebKitFormBoundaryuXDgAwSKKIGnITam # print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['mx1EBTtsOb0k96TUUW8XKbCGvK0Co3S6ZMlLvOuZOKAlO9nfhf6zol0V8KxRxbwT'], 'user': ['张开']}> # print(request.FILES) # <MultiValueDict: {'f1': [<InMemoryUploadedFile: 接口测试示例.xlsx (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)>]}> f1 = request.FILES.get('f1') print(f1) # 接口测试示例.xlsx book = xlrd.open_workbook(filename=None, file_contents=f1.read()) sheet = book.sheet_by_index(0) print(sheet.row_values(1)) # ['cnodejs项目', 'get /topics 主题首页', 'https://cnodejs.org/api/v1/topics', 'get', '', '{"success":true}'] return JsonResponse({"message": "upload successful"}) else: return render(request, 'upload.html') 

OK, digamos que não é bom, seca estaria terminado.

baixar

 

Use StreamingHttpResponse

 

vê no código principal:

from django.http import StreamingHttpResponse
def download(request): file=open('crm/models.py','rb') response =StreamingHttpResponse(file) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="models.py"' return response 

Use FileResponse

 

vê no código principal:

from django.http import FileResponse
def download(request): file=open('crm/models.py','rb') response =FileResponse(file) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="models.py"' return response 

Nome de arquivo não pode resolver os problemas em chinês

 

Se você é cuidadoso para tentar, você vai encontrar duas maneiras para baixar o acima filenamenão pode conter chinês, então como resolvê-lo? Para olhar para baixo!

from django.http import FileResponse
from django.utils.encoding import escape_uri_path   # 导入这个家伙 def download(request): file=open('crm/models.py','rb') response =FileResponse(file) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="{}.py"'.format(escape_uri_path("我是中文啦")) return response 

Não está resolvido! Perfeito! !

Acho que você gosta

Origin www.cnblogs.com/zhang-da/p/12575566.html
Recomendado
Clasificación