Gamelogic
Gamelogic

Reputation: 39

Filedownload Issue Django - File becomes practically empty

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

Answers (2)

Gamelogic
Gamelogic

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

Ykh
Ykh

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

Related Questions