mirror of
https://github.com/wagtail/wagtail.git
synced 2024-12-01 11:41:20 +01:00
add a sendfile class based view implementation
This commit is contained in:
parent
4ae735fae2
commit
58dfea096e
@ -97,3 +97,52 @@ method in your urls configuration:
|
||||
|
||||
url(r'^images/([^/]*)/(\d*)/([^/]*)/[^/]*$', ServeView.as_view(action='redirect'), name='wagtailimages_serve'),
|
||||
]
|
||||
|
||||
Integration with django-sendfile
|
||||
--------------------------------
|
||||
|
||||
`django-sendfile`_ offloads the job of transferring the image data to the web
|
||||
server instead of serving it directly from the Django application. This could
|
||||
greatly reduce server load in situations where your site has many images being
|
||||
downloaded but you're unable to use a :ref:`caching_proxy` or a CDN.
|
||||
|
||||
.. _django-sendfile: https://github.com/johnsensible/django-sendfile
|
||||
|
||||
You firstly need to install and configure django-sendfile and configure your
|
||||
web server to use it. If you haven't done this already, please refer to the
|
||||
`installation docs <https://github.com/johnsensible/django-sendfile#django-sendfile>`_.
|
||||
|
||||
To serve images with django-sendfile, you can use the ``SendFileView`` class.
|
||||
This view can be used out of the box:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from wagtail.wagtailimages.views.serve import SendFileView
|
||||
|
||||
urlpatterns = [
|
||||
...
|
||||
|
||||
url(r'^images/([^/]*)/(\d*)/([^/]*)/[^/]*$', SendFileView.as_view(), name='wagtailimages_serve'),
|
||||
]
|
||||
|
||||
You can customise it to override the backend defined in the ``SENDFILE_BACKEND``
|
||||
setting:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from wagtail.wagtailimages.views.serve import SendFileView
|
||||
from project.sendfile_backends import MyCustomBackend
|
||||
|
||||
class MySendFileView(SendFileView):
|
||||
backend = MyCustomBackend
|
||||
|
||||
You can also customise it to serve private files. For example, if the only need
|
||||
is to be authenticated (e.g. for Django >= 1.9):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from wagtail.wagtailimages.views.serve import SendFileView
|
||||
|
||||
class PrivateSendFileView(LoginRequiredMixin, SendFileView):
|
||||
raise_exception = True
|
||||
|
@ -58,6 +58,8 @@ Wagtail is tested on SQLite, and should work on other Django-supported database
|
||||
Public users
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. _caching_proxy:
|
||||
|
||||
Caching proxy
|
||||
-------------
|
||||
|
||||
|
10
wagtail/tests/dummy_sendfile_backend.py
Normal file
10
wagtail/tests/dummy_sendfile_backend.py
Normal file
@ -0,0 +1,10 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.http import HttpResponse
|
||||
|
||||
|
||||
def sendfile(request, filename, **kwargs):
|
||||
"""
|
||||
Dummy sendfile backend implementation.
|
||||
"""
|
||||
return HttpResponse('Dummy backend response')
|
@ -1,11 +1,12 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from django import forms, template
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test import TestCase
|
||||
from django.test import TestCase, override_settings
|
||||
from django.utils import six
|
||||
from mock import MagicMock
|
||||
from taggit.forms import TagField, TagWidget
|
||||
@ -21,6 +22,12 @@ from wagtail.wagtailimages.views.serve import ServeView, generate_signature, ver
|
||||
|
||||
from .utils import Image, get_test_image_file
|
||||
|
||||
try:
|
||||
import sendfile # noqa
|
||||
sendfile_mod = True
|
||||
except:
|
||||
sendfile_mod = False
|
||||
|
||||
|
||||
class TestImageTag(TestCase):
|
||||
def setUp(self):
|
||||
@ -354,6 +361,36 @@ class TestFrontendServeView(TestCase):
|
||||
self.assertEqual(response.status_code, 410)
|
||||
|
||||
|
||||
class TestFrontendSendfileView(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.image = Image.objects.create(
|
||||
title="Test image",
|
||||
file=get_test_image_file(),
|
||||
)
|
||||
|
||||
@override_settings(SENDFILE_BACKEND='sendfile.backends.development')
|
||||
@unittest.skipIf(not sendfile_mod, 'Missing django-sendfile app.')
|
||||
def test_sendfile_nobackend(self):
|
||||
signature = generate_signature(self.image.id, 'fill-800x600')
|
||||
response = self.client.get(reverse('wagtailimages_sendfile',
|
||||
args=(signature, self.image.id,
|
||||
'fill-800x600')))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response['Content-Type'], 'image/png')
|
||||
|
||||
@override_settings(SENDFILE_BACKEND='sendfile.backends.development')
|
||||
def test_sendfile_dummy_backend(self):
|
||||
signature = generate_signature(self.image.id, 'fill-800x600')
|
||||
response = self.client.get(reverse('wagtailimages_sendfile_dummy',
|
||||
args=(signature, self.image.id,
|
||||
'fill-800x600')))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(response.content, 'Dummy backend response')
|
||||
|
||||
|
||||
class TestRect(TestCase):
|
||||
def test_init(self):
|
||||
rect = Rect(100, 150, 200, 250)
|
||||
|
@ -2,10 +2,13 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from wagtail.wagtailimages.views.serve import ServeView
|
||||
from wagtail.tests import dummy_sendfile_backend
|
||||
from wagtail.wagtailimages.views.serve import SendFileView, ServeView
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^actions/serve/(.*)/(\d*)/(.*)/[^/]*', ServeView.as_view(action='serve'), name='wagtailimages_serve_action_serve'),
|
||||
url(r'^actions/redirect/(.*)/(\d*)/(.*)/[^/]*', ServeView.as_view(action='redirect'), name='wagtailimages_serve_action_redirect'),
|
||||
url(r'^custom_key/(.*)/(\d*)/(.*)/[^/]*', ServeView.as_view(key='custom'), name='wagtailimages_serve_custom_key'),
|
||||
url(r'^sendfile/(.*)/(\d*)/(.*)/[^/]*', SendFileView.as_view(), name='wagtailimages_sendfile'),
|
||||
url(r'^sendfile-dummy/(.*)/(\d*)/(.*)/[^/]*', SendFileView.as_view(backend=dummy_sendfile_backend.sendfile), name='wagtailimages_sendfile_dummy'),
|
||||
]
|
||||
|
@ -14,6 +14,7 @@ from django.utils.decorators import classonlymethod
|
||||
from django.utils.six import text_type
|
||||
from django.views.generic import View
|
||||
|
||||
from wagtail.utils.sendfile import sendfile
|
||||
from wagtail.wagtailimages.exceptions import InvalidFilterSpecError
|
||||
from wagtail.wagtailimages.models import SourceImageIOError, get_image_model
|
||||
|
||||
@ -78,3 +79,10 @@ class ServeView(View):
|
||||
|
||||
|
||||
serve = ServeView.as_view()
|
||||
|
||||
|
||||
class SendFileView(ServeView):
|
||||
backend = None
|
||||
|
||||
def serve(self, rendition):
|
||||
return sendfile(self.request, rendition.file.path, backend=self.backend)
|
||||
|
Loading…
Reference in New Issue
Block a user