91👍
Well, re-encoding is needed sometimes (i.e. applying an watermark over an image while keeping the original untouched), but for the most simple of cases you can use:
try:
with open(valid_image, "rb") as f:
return HttpResponse(f.read(), content_type="image/jpeg")
except IOError:
red = Image.new('RGBA', (1, 1), (255,0,0,0))
response = HttpResponse(content_type="image/jpeg")
red.save(response, "JPEG")
return response
10👍
Make use of FileResponse
A cleaner way, here we dont have to worry about the Content-Length
and Content-Type
headers, they are automatically added by guessing the contents of open()
.
from django.http import FileResponse
def send_file(response):
img = open('media/hello.jpg', 'rb')
response = FileResponse(img)
return response
- [Django]-How can I have two foreign keys to the same model in Django?
- [Django]-Populating django field with pre_save()?
- [Django]-Django FileField with upload_to determined at runtime
1👍
Just stumbled on the somewhat bad advice (for production) and thought I would mention X-Sendfile which works with both Apache and Nginx and probably other webservers too.
https://pythonhosted.org/xsendfile/
Modern Web servers like Nginx are generally able to serve files faster, more efficiently and more reliably than any Web application they host. These servers are also able to send to the client a file on disk as specified by the Web applications they host. This feature is commonly known as X-Sendfile.
This simple library makes it easy for any WSGI application to use X-Sendfile, so that they can control whether a file can be served or what else to do when a file is served, without writing server-specific extensions. Use cases include:
Restrict document downloads to authenticated users.
Log who’s downloaded a file. Force a file to be downloaded instead of
rendered by the browser, or serve it with a name different from the
one on disk, by setting the Content-Disposition header.
The basic idea is you open the file and pass that handle back to the webserver which then returns the bytes to the client, freeing your python code to handle the next request. This is far more performant than the solution above since a slow client on the other end could hang your python thread for as long as it takes to download the file.
Here is a repo that shows how to do this for various webservers and although it is pretty old, it will at least give you an idea of what you need to do. https://github.com/johnsensible/django-sendfile
- [Django]-Django Rest Framework: turn on pagination on a ViewSet (like ModelViewSet pagination)
- [Django]-Get current user in Model Serializer
- [Django]-Django REST Framework: how to substitute null with empty string?
0👍
Using the more recent view class pattern, here is what I did.
class FileView(View):
def get(self, request, *args, **kwargs):
img = open('path/image.png', 'rb')
response = FileResponse(img)
return response
- [Django]-How to make python on Heroku https only?
- [Django]-Django development IDE
- [Django]-Define css class in django Forms