I have an idea that after authentication / permissions, the file is stored in the FileField file.
from django.http import StreamingHttpResponse
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from wsgiref.util import FileWrapper
import mimetypes
from myapp.models import MyModel
class ExampleViewSet(viewsets.ViewSet):
@detail_route(methods=['GET'])
def download(self, *args, **kwargs):
pk = self.request.parser_context['kwargs'].get('pk', None)
if pk is None:
raise exceptions.ParseError('no pk')
instance = MyModel.objects.get(pk=pk)
filename = instance.file_field.name.split('/')[-1]
mime = mimetypes.guess_type(filename)[0]
file = instance.file_field.file
response = StreamingHttpResponse(
FileWrapper(open(file, 'rb'), 10240))
response['Content-Type'] = "{0}; charset=utf-8".format(mime)
response['Content-Length'] = file.size
response[
'Content-Disposition'] = 'attachment; filename={0}'.format(filename)
return response
The file itself is a 3.7MB file that was previously uploaded by the user. In the download directory, the file is 3.7MB and opens correctly. when downloading via a browser (Firefox or Chrome) the file has 7.0 MB and is damaged (does not have the correct header for jpegs, which should start with two specific bytes) when downloading from curl or wget, the file is 3.7 MB and opens correctly
Below is the result of twisting the response fields using curl -v
curl -v http://localhost:3000/api/school_admin/posters/7/download?token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SndhR0Z6YUNJNkltSmpjbmx3ZEY5emFHRXlOVFlrSkRKaUpERXlKR2hzVlUxd2QyOWpTM1pMTnk1VlRuSXZPR1ZNVWs5aFJEVjBVbmR2V21FeVVGVlZiWGhxTTJWb1UzZFhla1JNU3k5RmFqZFRJaXdpY0hKdlptbHNaVjl3YXlJNk15d2laWGh3SWpveE5EY3lOalUyTWpFMGZRLmV6OGg5SWVwLUozYjdQcHJLVGJCZWlSSjJPN1JRdnItaFVuLVg0dmdLZGdtRGdQV0s2ZzkzdktialN2Uy1EVTVkM1hRc2hRZ3YxeVZmQlJhUDBBVlhB -o test.jpeg
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/school_admin/posters/7/download?token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SndhR0Z6YUNJNkltSmpjbmx3ZEY5emFHRXlOVFlrSkRKaUpERXlKR2hzVlUxd2QyOWpTM1pMTnk1VlRuSXZPR1ZNVWs5aFJEVjBVbmR2V21FeVVGVlZiWGhxTTJWb1UzZFhla1JNU3k5RmFqZFRJaXdpY0hKdlptbHNaVjl3YXlJNk15d2laWGh3SWpveE5EY3lOalUyTWpFMGZRLmV6OGg5SWVwLUozYjdQcHJLVGJCZWlSSjJPN1JRdnItaFVuLVg0dmdLZGdtRGdQV0s2ZzkzdktialN2Uy1EVTVkM1hRc2hRZ3YxeVZmQlJhUDBBVlhB HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Mon, 29 Aug 2016 18:31:30 GMT
< server: WSGIServer/0.2 CPython/3.4.3
< allow: GET, DELETE, HEAD, OPTIONS
< content-type: image/jpeg; charset=utf-8
< vary: Accept
< content-length: 3947925
< content-disposition: attachment; filename=poster_28F7bdD4caAbCc583831c9E7C9baDaEC88Ecbde6FBAA6aE71cAdC09fd8EFCF7BD515155bec1C3FC6f01c6FEf5Ba76e41952E_Colosseum_in_Rome_Italy_-_April_2007.jpg
< x-frame-options: SAMEORIGIN
< via: 1.1 fedora
< Connection: keep-alive
<
{ [15913 bytes data]
100 3855k 100 3855k 0 0 141M 0 --:--:-- --:--:-- --:--:-- 144M
* Connection #0 to host localhost left intact
source
share