Django - el archivo de carga y descarga

formulario de carga de forma

 

No tantos cosa, vistazo a un ejemplo:
código de front-end es 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> 

En general, cuando un envío del formulario forma normal, encabezado de la solicitud CONTENT_TYPE: application/x-www-form-urlencoded, y después los datos se transmiten en forma de pares de valores clave, el servidor desde request.POSTel valor, no hay duda, y CONTENT_TYPE: application/x-www-form-urlencodedeste tipo de codificación para la mayoría de los casos, todo lo muy bueno.

Y decir que el uso de la forma formulario para cargar un archivo, hay que decir unas palabras hacia arriba.
En un primer momento, el protocolo HTTP no está aspectos funcionales de carga de archivos hasta RFC1867 añadir esta funcionalidad al protocolo http. RFC1867 define en el curso de  formla etiqueta  method debe ser  POST, enctype = "multipart/form-data" así <input type = "file">.
Por lo tanto, cuando se utiliza el formulario de formulario para subir documentos, solicitud de cabecera content_typees multipart/form-dataesta forma, por lo que tenemos que añadir una forma de etiqueta enctype="multipart/form-dataatributos para su identificación.
Si puede imprimir encabezado de solicitud para subir archivos, encontrará CONTENT_TYPEes esto content_type:multipart/form-data; boundary=----WebKitFormBoundarylZZyJUkrgm6h34DU, que boundary=----WebKitFormBoundarylZZyJUkrgm6h34DUlo es?
En multipart/form-data detrás boundaryy una cadena de caracteres, esto es el delimitador, una pila detrás de la cadena generada al azar, con el fin de prevenir la ocurrencia delimitador servidor de archivo de carga no puede identificar correctamente el principio del archivo. Eso delimitador y atenuarla?
Para la solicitud del poste cargue un archivo, no usamos el protocolo http original, por lo multipart / petición form-data se basa en la petición http post original método viene, entonces se dice que la diferencia entre esta nueva manera de enviar la solicitud:

  1. Solicitar una cabeza diferente, una solicitud de carga de archivos contentType = multipart/form-dataes necesario, pero después no es, después de todo, no sólo se carguen archivos publican ~.
  2. cuerpo de la solicitud diferente, es diferente se refiere aquí a la antigua (solicitud de carga) se debe utilizar entre cada delimitador de campo para separar la transmisión de contenido, como el contenido y archivos de texto necesitan separadas, de lo contrario el servidor no hay manera de la resolución de archivo normal, que por supuesto hay ningún delimitador posterior directamente key:valuetransmitida en forma ella.

Por supuesto, el curvado alrededor de unas pocas palabras no pueden explicar claramente, sabemos cómo utilizar en la línea.
Look vistas Vista de un proceso:

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": ""}) 

subir archivos ajax

 

La parte delantera del archivo:

<!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 con el fin de evitar la falsa solicitud contentType jQuery cabeza content_typeopera, perdiendo así delimitador, el servidor de archivos no puede resolver correctamente.
En el uso de método jQuery $ .ajax () cuando el parámetro predeterminado processData a verdadero (que es un jQuery única), el valor predeterminado será el caso de la secuencia de datos transmitida a adaptarse aplicación tipo de contenido predeterminado / x-www-form -urlencoded
tiempo si desea no quieren enviar información a la necesidad de ajustar manualmente a false.
Echemos un vistazo en el back-end de views.pycómo hacer frente a:

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, decir nada bueno, estaría terminado seco.

descargar

 

uso StreamingHttpResponse

 

vistas en el 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 

uso FileResponse

 

vistas en el 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 

Nombre de archivo no puede resolver los problemas en China

 

Si usted tiene cuidado de tratar, se encuentran dos formas de descargar lo anterior filenameno puede contener chino, entonces, ¿cómo se puede solucionar? Mirar hacia abajo!

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 

No está resuelto! Perfecto! !

formulario de carga de forma

 

No tantos cosa, vistazo a un ejemplo:
código de front-end es 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> 

En general, cuando un envío del formulario forma normal, encabezado de la solicitud CONTENT_TYPE: application/x-www-form-urlencoded, y después los datos se transmiten en forma de pares de valores clave, el servidor desde request.POSTel valor, no hay duda, y CONTENT_TYPE: application/x-www-form-urlencodedeste tipo de codificación para la mayoría de los casos, todo lo muy bueno.

Y decir que el uso de la forma formulario para cargar un archivo, hay que decir unas palabras hacia arriba.
En un primer momento, el protocolo HTTP no está aspectos funcionales de carga de archivos hasta RFC1867 añadir esta funcionalidad al protocolo http. RFC1867 define en el curso de  formla etiqueta  method debe ser  POST, enctype = "multipart/form-data" así <input type = "file">.
Por lo tanto, cuando se utiliza el formulario de formulario para subir documentos, solicitud de cabecera content_typees multipart/form-dataesta forma, por lo que tenemos que añadir una forma de etiqueta enctype="multipart/form-dataatributos para su identificación.
Si puede imprimir encabezado de solicitud para subir archivos, encontrará CONTENT_TYPEes esto content_type:multipart/form-data; boundary=----WebKitFormBoundarylZZyJUkrgm6h34DU, que boundary=----WebKitFormBoundarylZZyJUkrgm6h34DUlo es?
En multipart/form-data detrás boundaryy una cadena de caracteres, esto es el delimitador, una pila detrás de la cadena generada al azar, con el fin de prevenir la ocurrencia delimitador servidor de archivo de carga no puede identificar correctamente el principio del archivo. Eso delimitador y atenuarla?
Para la solicitud del poste cargue un archivo, no usamos el protocolo http original, por lo multipart / petición form-data se basa en la petición http post original método viene, entonces se dice que la diferencia entre esta nueva manera de enviar la solicitud:

  1. Solicitar una cabeza diferente, una solicitud de carga de archivos contentType = multipart/form-dataes necesario, pero después no es, después de todo, no sólo se carguen archivos publican ~.
  2. cuerpo de la solicitud diferente, es diferente se refiere aquí a la antigua (solicitud de carga) se debe utilizar entre cada delimitador de campo para separar la transmisión de contenido, como el contenido y archivos de texto necesitan separadas, de lo contrario el servidor no hay manera de la resolución de archivo normal, que por supuesto hay ningún delimitador posterior directamente key:valuetransmitida en forma ella.

Por supuesto, el curvado alrededor de unas pocas palabras no pueden explicar claramente, sabemos cómo utilizar en la línea.
Look vistas Vista de un proceso:

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": ""}) 

subir archivos ajax

 

La parte delantera del archivo:

<!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 con el fin de evitar la falsa solicitud contentType jQuery cabeza content_typeopera, perdiendo así delimitador, el servidor de archivos no puede resolver correctamente.
En el uso de método jQuery $ .ajax () cuando el parámetro predeterminado processData a verdadero (que es un jQuery única), el valor predeterminado será el caso de la secuencia de datos transmitida a adaptarse aplicación tipo de contenido predeterminado / x-www-form -urlencoded
tiempo si desea no quieren enviar información a la necesidad de ajustar manualmente a false.
Echemos un vistazo en el back-end de views.pycómo hacer frente a:

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, decir nada bueno, estaría terminado seco.

descargar

 

uso StreamingHttpResponse

 

vistas en el 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 

uso FileResponse

 

vistas en el 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 

Nombre de archivo no puede resolver los problemas en China

 

Si usted tiene cuidado de tratar, se encuentran dos formas de descargar lo anterior filenameno puede contener chino, entonces, ¿cómo se puede solucionar? Mirar hacia abajo!

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 

No está resuelto! Perfecto! !

Supongo que te gusta

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