tutorial para instalar framework descargar python django download

python - para - instalar django en windows 10



Que Django sirva archivos descargables (14)

Quiero que los usuarios del sitio puedan descargar archivos cuyas rutas estén ocultas para que no puedan descargarse directamente.

Por ejemplo, me gustaría que la URL fuera algo como esto ", http://example.com/download/?f=somefile.txt

Y en el servidor, sé que todos los archivos descargables residen en una carpeta "/ home / user / files /".

¿Hay alguna manera de hacer que Django sirva ese archivo para descargarlo en lugar de intentar encontrar una URL y Ver para mostrarlo?


Debe usar las apis de sendfile dadas por servidores populares como apache o nginx en producción. Durante muchos años, estuve usando la aplicación sendfile de estos servidores para proteger archivos. Luego creó una aplicación django sencilla basada en middleware para este propósito, adecuada tanto para desarrollo como para producción. here puede acceder al código fuente.
ACTUALIZACIÓN: en la nueva versión, el proveedor de python usa django FileResponse si está disponible y también agrega soporte para muchas implementaciones de servidores desde lighthttp, caddy a hiawatha

Uso

pip install django-fileprovider

  • agrega la aplicación fileprovider a la configuración de INSTALLED_APPS ,
  • agregar fileprovider.middleware.FileProviderMiddleware a la configuración de MIDDLEWARE_CLASSES
  • establezca la configuración de FILEPROVIDER_NAME en nginx o apache en producción, de forma predeterminada es python para fines de desarrollo.

en sus vistas basadas en clases o funciones, establezca el valor del X-File encabezado de respuesta en la ruta absoluta al archivo. Por ejemplo,

def hello(request): // code to check or protect the file from unauthorized access response = HttpResponse() response[''X-File''] = ''/absolute/path/to/file'' return response

django-fileprovider mejorado de manera que su código solo necesitará una modificación mínima.

Configuracion nginx

Para proteger el archivo del acceso directo, puede configurar la configuración como

location /files/ { internal; root /home/sideffect0/secret_files/; }

Aquí nginx establece una ubicación url /files/ solo acceso interno, si está utilizando la configuración anterior, puede configurar X-File como,

response[''X-File''] = ''/files/filename.extension''

Al hacer esto con la configuración de nginx, el archivo estará protegido y también puede controlar el archivo desde las views django


Django recomienda que use otro servidor para servir medios estáticos (otro servidor que se ejecuta en la misma máquina está bien). Recomiendan el uso de servidores como lighttp .

Esto es muy simple de configurar. Sin embargo. si se genera ''somefile.txt'' a pedido (el contenido es dinámico), es posible que desee que django lo sirva.

Django Docs - Archivos estáticos


He enfrentado el mismo problema más de una vez y, por lo tanto, lo he implementado utilizando el módulo xsendfile y los decoradores de vistas de autenticación en la django-filelibrary . Siéntase libre de usarlo como inspiración para su propia solución.

django-filelibrary


Otro proyecto para echar un vistazo a: http://readthedocs.org/docs/django-private-files/en/latest/usage.html Parece promisorio, pero no lo he probado.

Básicamente, el proyecto abstrae la configuración mod_xsendfile y le permite hacer cosas como:

from django.db import models from django.contrib.auth.models import User from private_files import PrivateFileField def is_owner(request, instance): return (not request.user.is_anonymous()) and request.user.is_authenticated and instance.owner.pk = request.user.pk class FileSubmission(models.Model): description = models.CharField("description", max_length = 200) owner = models.ForeignKey(User) uploaded_file = PrivateFileField("file", upload_to = ''uploads'', condition = is_owner)


Para "lo mejor de los dos mundos", puede combinar la solución de S.Lott con el módulo xsendfile : django genera la ruta al archivo (o el archivo en sí), pero Apache / Lighttpd maneja el archivo real. Una vez que haya configurado mod_xsendfile, la integración con su vista toma algunas líneas de código:

from django.utils.encoding import smart_str response = HttpResponse(mimetype=''application/force-download'') # mimetype is replaced by content_type for django 1.7 response[''Content-Disposition''] = ''attachment; filename=%s'' % smart_str(file_name) response[''X-Sendfile''] = smart_str(path_to_file) # It''s usually a good idea to set the ''Content-Length'' header too. # You can also set any other required headers: Cache-Control, etc. return response

Por supuesto, esto solo funcionará si usted tiene control sobre su servidor, o si su compañía de alojamiento ya ha configurado mod_xsendfile.

EDITAR:

mimetype es reemplazado por content_type para django 1.7

response = HttpResponse(content_type=''application/force-download''

EDITAR: Para nginx verifique this , usa X-Accel-Redirect lugar del encabezado de apache X-Sendfile.


Para una solución muy simple pero no eficiente o escalable , solo puede usar la vista integrada de django serve . Esto es excelente para prototipos rápidos o trabajos únicos, pero como se mencionó a lo largo de esta pregunta, debe usar algo como apache o nginx en producción.

from django.views.static import serve filepath = ''/some/path/to/local/file.txt'' return serve(request, os.path.basename(filepath), os.path.dirname(filepath))


Probé la solución @Rocketmonkeys pero los archivos descargados se almacenaron como * .bin y se les dieron nombres aleatorios. Eso no está bien, por supuesto. Añadir otra línea de @ elo80ka solucionó el problema.
Aquí está el código que estoy usando ahora:

from wsgiref.util import FileWrapper from django.http import HttpResponse filename = "/home/-addict/private-folder(not-porn)/image.jpg" wrapper = FileWrapper(file(filename)) response = HttpResponse(wrapper, content_type=''text/plain'') response[''Content-Disposition''] = ''attachment; filename=%s'' % os.path.basename(filename) response[''Content-Length''] = os.path.getsize(filename) return response

Ahora puede almacenar archivos en un directorio privado (no dentro de / media ni / public_html) y exponerlos a través de django a ciertos usuarios o bajo ciertas circunstancias.
Espero eso ayude.

Gracias a @ elo80ka, @ S.Lott y @Rocketmonkeys por las respuestas, obtuve la solución perfecta combinándolas todas =)




S.Lott tiene la solución "buena" / simple, y elo80ka tiene la solución "mejor" / eficiente. Aquí hay una solución "mejor" / intermedia: no hay configuración del servidor, pero es más eficiente para archivos grandes que la solución ingenua:

http://djangosnippets.org/snippets/365/

Básicamente, Django aún maneja el archivo, pero no carga todo en la memoria de una vez. Esto permite que su servidor sirva (lentamente) un archivo grande sin aumentar el uso de la memoria.

Nuevamente, el archivo X-SendFile de S.Lott sigue siendo mejor para archivos más grandes. Pero si no puedes o no quieres molestarte con eso, entonces esta solución intermedia te dará una mayor eficiencia sin la molestia.


Se mencionó anteriormente que el método mod_xsendfile no permite caracteres no ASCII en los nombres de archivo.

Por esta razón, tengo un parche disponible para mod_xsendfile que permitirá que se envíe cualquier archivo, siempre que el nombre esté codificado como URL y el encabezado adicional:

X-SendFile-Encoding: url

Se envía también.

http://ben.timby.com/?p=149


Solo mencionando el objeto FileResponse disponible en Django 1.10

Edición: Me topé con mi propia respuesta mientras buscaba una forma fácil de transmitir archivos a través de Django, así que aquí hay un ejemplo más completo (para mí en el futuro). Se supone que el nombre de FileField es imported_file

vistas.py

from django.views.generic.detail import DetailView from django.http import FileResponse class BaseFileDownloadView(DetailView): def get(self, request, *args, **kwargs): filename=self.kwargs.get(''filename'', None) if filename is None: raise ValueError("Found empty filename") some_file = self.model.objects.get(imported_file=filename) response = FileResponse(some_file.imported_file, content_type="text/csv") # https://docs.djangoproject.com/en/1.11/howto/outputting-csv/#streaming-large-csv-files response[''Content-Disposition''] = ''attachment; filename="%s"''%filename return response class SomeFileDownloadView(BaseFileDownloadView): model = SomeModel

urls.py

... url(r''^somefile/(?P<filename>[-/w_//-//.]+)$'', views.SomeFileDownloadView.as_view(), name=''somefile-download''), ...


Una "descarga" es simplemente un cambio de encabezado HTTP.

Consulte http://docs.djangoproject.com/en/dev/ref/request-response/#telling-the-browser-to-treat-the-response-as-a-file-attachment para http://docs.djangoproject.com/en/dev/ref/request-response/#telling-the-browser-to-treat-the-response-as-a-file-attachment cómo responder con una descarga .

Solo necesita una definición de URL para "/download" .

El diccionario GET o POST tendrá la información "f=somefile.txt" .

Su función de vista simplemente fusionará la ruta base con el valor " f ", abrirá el archivo, creará y devolverá un objeto de respuesta. Debe ser menos de 12 líneas de código.


def qrcodesave(request): import urllib2; url ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=s&chld=H|0"; opener = urllib2.urlopen(url); content_type = "application/octet-stream" response = HttpResponse(opener.read(), content_type=content_type) response["Content-Disposition"]= "attachment; filename=aktel.png" return response