Reputation: 39
I am having the following issue with filedownload from product views in Django product site:
The issue: Filesize of downloaded file is practically 1kb whilst it should be a normal image filesize (20kb in my example).
So the to-download file is present in static folder of the product instance.id (static_cdn/protected/instance.id/image.jpg -- context: product site where user can upload a file to the corresponding product view).
However, whenever I try to download it from the product view, it downloads the file with the right filename (including the added instance.id number before the filename), but the filesize is almost null. I think it has to do the with the class ProductDownloadView.
Please find the relevant codes below:
views.py:
class ProductDownloadView(MultiSlugMixin, DetailView):
model = Product
def get(self, request, *args, **kwargs):
obj = self.get_object()
filepath = os.path.join(settings.PROTECTED_ROOT, obj.media.path)
response = HttpResponse(file(filepath), content_type="application/force-download")
response["Content-Disposition"] = "attachment;filename=%s" % (obj.media.name)
response["X-SendFile"] = str(obj.media.name)
return response
models.py
class Product(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
managers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="managers_product")
media = models.FileField(blank=True,
null=True,
upload_to=download_media_location,
storage=FileSystemStorage(location=settings.PROTECTED_ROOT))
def __unicode__(self):
return self.title
def get_absolute_url(self):
view_name = "products:detail_slug"
return reverse(view_name, kwargs={"slug": self.slug})
def get_download(self):
view_name = "products:download_slug"
url = reverse(view_name, kwargs={"slug": self.slug})
return url
Please find below the printed obj, filepath and response variables:
print obj: pr8
print filepath: C:\Users\xx\xx\xx\market_place\static_cdn\protected\8\Beach.jpg
print response: Content-Type: application/force-download Content-Disposition: attachment;filename=8/Beach.jpg X-SendFile: 8/Beach.jpg
���� JFIF �� C
[21/Jun/2017 02:17:05] "GET /products/pr8/download/ HTTP/1.1" 200 52
Upvotes: 1
Views: 443
Reputation: 39
I think I've found the answer. I got the file-download to work by using the open method instead of the file method. Because of this solution I am deviating from a tutorial, but at least I got the job done.
So I got it working by changing the following rule:
response = HttpResponse(file(filepath), content_type="application/force-download")
into:
response = HttpResponse(open(filepath, "rb"), content_type="application/force-download")
So basically adding a mode to the function. Even the file method works after adding the mode "rb".
Upvotes: 1
Reputation: 7717
try this:
response = HttpResponse(content_type="image/jpeg")
response['X-Sendfile'] = obj.media.path
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(photo.image.name)
Upvotes: 0