我正在使用Django 1.7和Python 3.4。
我有一个像这样的模型:
class ImageModel(models.Model):
image = models.ImageField(verbose_name='image', upload_to='uploaded_images/')
现在我要下载保存在/ static / uploaded_images /中的图像。
例如,我有一个这样的链接:www.example.com/image/download/1
,其中1是ImageModel对象的id。
现在我有了一个观点:
def download_image(request, image_id):
img = ImageModel.objects.get(id=image_id)
( what I need to do? )
下一步是什么?如何创建一个强制下载该图像的视图?
答案 0 :(得分:3)
你可以尝试这个代码,也许需要一些注意事项:
from django.core.servers.basehttp import FileWrapper
import mimetypes
def download_image(request, image_id):
img = ImageModel.objects.get(id=image_id)
wrapper = FileWrapper(open(img.file)) # img.file returns full path to the image
content_type = mimetypes.guess_type(filename)[0] # Use mimetypes to get file type
response = HttpResponse(wrapper,content_type=content_type)
response['Content-Length'] = os.path.getsize(img.file)
response['Content-Disposition'] = "attachment; filename=%s" % img.name
return response
我假设您的.name
中有一个字段ImageModel
,以便在倒数第二行...filename=%s" % img.name
中获取该文件的名称您应该编辑代码以适合您的项目。
ImageField 中的字段为file
,在此处的代码中我使用img.file
来获取路径对于文件,您应该更改img.YOUR_IMAGE_FIELD.file
或获取图像路径所需的任何内容
答案 1 :(得分:1)
您需要使用Content-Disposition
标题,请点击此处:
Generating file to download with Django
Django Serving a Download File
答案 2 :(得分:0)
另外两个答案还可以,但是出于性能原因,不推荐使用Django提供静态文件的许多地方做广告。最好使用您的Web服务器(nginx / apache ...)来提供它。
您不需要额外的视图来提供静态文件。只需在模板中呈现指向该文件的链接:
<a href="{{object.image.url}} download">Download this image!</a>
其中object
是ImageModel
的实例。
请参阅django.db.models.fields.files.FieldFile.url
如果你真的想在www.example.com/image/download/1
这样的网址中拥有一个视图,你只需编写一个重定向到从该字段获取的图像网址的视图。
答案 3 :(得分:0)
基于类的视图类型示例就像这样(我使用python-magic来获取文件的正确内容类型):
import os
import magic
from django.views.generic import View
from django.http import HttpResponse
from .models import ImageModel
class ImageDownloadView(View):
def get(self, request, *args, **kwargs):
image = ImageModel.objects.get(pk=self.kwargs['image_id'])
image_buffer = open(image.file.path, "rb").read()
content_type = magic.from_buffer(image_buffer, mime=True)
response = HttpResponse(image_buffer, content_type=content_type);
response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(image.file.path)
return response
这适用于Django 1.10.7但不应该与Django 1.7不同
答案 4 :(得分:-1)
以下是包含任何字符类型
的文件的跨浏览器安全下载# Even better as it works in any browser (mobile and desktop)
def safe_name(file_name):
"""
Generates a safe file name, even those containing characters like ? and &
And your Kanji and Cyrillics are supported!
"""
u_file_name = file_name.encode('utf-8')
s_file_name = re.sub('[\x00-\xFF]', lambda c: '%%%02x' % ord(c.group(0)), u_file_name)
return s_file_name
# Handled by url(r'^/image/download/(\d+)/.+$
def safe_download_image(request, image_id):
"""
Safely downloads the file because the filename is part of the URL
"""
img = ImageModel.objects.get(id=image_id)
wrapper = FileWrapper(open(img.file)) # img.file returns full path to the image
content_type = mimetypes.guess_type(filename)[0] # Use mimetypes to get file type
response = HttpResponse(wrapper,content_type=content_type)
response['Content-Length'] = os.path.getsize(img.file)
# This works for most browsers, but IE will complain sometimes
response['Content-Disposition'] = "attachment;"
return response
def download_image(request, image_id):
img = ImageModel.objects.get(id=image_id)
redirect_do = safe_name(img.name)
return HttpResponseRedirect('/image/download/' + img_id + '/' + redirect_to)
答案 5 :(得分:-1)
这不起作用。我做了这样的事情:
wrapper = FileWrapper(img.file) # img.file returns full path to the image
content_type = mimetypes.guess_type(str(img.file))[0] # Use mimetypes to get file type
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Length'] = os.path.getsize(str(img.file))
response['Content-Disposition'] = "attachment; filename=%s" % img.name
其中img
指向我的ImageField
字段。文件已下载,但我无法打开它。 xUbuntu image viewer seys'不是JPEG文件。以0x89 0x50'