Refs #23 - Implemented and tested StorageDownloadView. This StorageDownloadView is to replace an use case of former DownloadView.

This commit is contained in:
Benoît Bryon 2013-02-06 18:59:22 +01:00
parent 5c91a53f40
commit e94054bcba
8 changed files with 73 additions and 11 deletions

View file

@ -4,7 +4,12 @@ Changelog
1.1 (unreleased)
----------------
- Nothing changed yet.
**Backward incompatible changes.**
- Download views and response now use file wrappers. Most logic around file
attributes, formerly in views, moved to wrappers.
- Replaced DownloadView by PathDownloadView and StorageDownloadView. Use the
right one depending on the use case.
1.0 (2012-12-04)

5
README
View file

@ -1,5 +1,5 @@
###################
Django-DownloadView
django-downloadview
###################
Django-DownloadView provides (class-based) generic download views for Django.
@ -22,8 +22,9 @@ Example, in some urls.py:
Several views are provided to cover frequent use cases:
* ``PathDownloadView`` when you have an absolute filename.
* ``ObjectDownloadView`` when you have a model with a file field.
* ``StorageDownloadView`` when you manage files in a storage.
* ``PathDownloadView`` when you have an absolute filename on local filesystem.
See :doc:`views` for details.

View file

@ -49,12 +49,22 @@ class PathDownloadViewTestCase(DownloadTestCase):
class CustomPathDownloadViewTestCase(DownloadTestCase):
"""Test "fixture_from_path" view."""
def test_download_hello_world(self):
"""fixture_from_path view can return hello-world.txt as attachement."""
"""fixture_from_path view returns hello-world.txt as attachement."""
download_url = reverse('fixture_from_path', args=['hello-world.txt'])
response = self.client.get(download_url)
self.assertDownloadHelloWorld(response)
class StorageDownloadViewTestCase(DownloadTestCase):
"""Test "fixture_from_storage" view."""
def test_download_hello_world(self):
"""fixture_from_storage view returns hello-world.txt as attachement."""
download_url = reverse('fixture_from_storage',
args=['hello-world.txt'])
response = self.client.get(download_url)
self.assertDownloadHelloWorld(response)
class ObjectDownloadViewTestCase(DownloadTestCase):
"""Test generic ObjectDownloadView."""
@temporary_media_root()

View file

@ -5,6 +5,14 @@ from django.conf.urls import patterns, url
urlpatterns = patterns(
'demoproject.download.views',
# Model-based downloads.
url(r'^document/(?P<slug>[a-zA-Z0-9_-]+)/$',
'download_document',
name='document'),
# Storage-based downloads.
url(r'^storage/(?P<path>[a-zA-Z0-9_-]+\.[a-zA-Z0-9]{1,4})$',
'download_fixture_from_storage',
name='fixture_from_storage'),
# Path-based downloads.
url(r'^hello-world\.txt$',
'download_hello_world',
@ -12,8 +20,4 @@ urlpatterns = patterns(
url(r'^path/(?P<path>[a-zA-Z0-9_-]+\.[a-zA-Z0-9]{1,4})$',
'download_fixture_from_path',
name='fixture_from_path'),
# Model-based downloads.
url(r'^document/(?P<slug>[a-zA-Z0-9_-]+)/$',
'download_document',
name='document'),
)

View file

@ -2,7 +2,10 @@
"""Demo download views."""
from os.path import abspath, dirname, join
from django_downloadview.views import ObjectDownloadView, PathDownloadView
from django.core.files.storage import FileSystemStorage
from django_downloadview.views import (ObjectDownloadView, PathDownloadView,
StorageDownloadView)
from demoproject.download.models import Document
@ -18,6 +21,9 @@ fixtures_dir = join(app_dir, 'fixtures')
hello_world_path = join(fixtures_dir, 'hello-world.txt')
"""Path to a text file that says 'Hello world!'."""
fixtures_storage = FileSystemStorage(location=fixtures_dir)
"""Storage for fixtures."""
# Here are the views.
@ -50,5 +56,10 @@ download_fixture_from_path = CustomPathDownloadView.as_view()
"""Pre-configured :py:class:`CustomPathDownloadView`."""
download_fixture_from_storage = StorageDownloadView.as_view(
storage=fixtures_storage)
"""Pre-configured view using a storage."""
download_document = ObjectDownloadView.as_view(model=Document)
"""Pre-configured download view for :py:class:`Document` model."""

View file

@ -13,6 +13,9 @@
<li><a href="{% url 'fixture_from_path' 'hello-world.txt' %}">
Download files using PathDownloadView and relative path in URL.
</a></li>
<li><a href="{% url 'fixture_from_storage' 'hello-world.txt' %}">
Download files using StorageDownloadView and path in URL.
</a></li>
<li><a href="{% url 'document' 'hello-world' %}">
ObjectDownloadView
</a></li>

View file

@ -98,10 +98,27 @@ class PathDownloadView(BaseDownloadView):
return File(open(self.get_path()))
class StorageDownloadView():
class StorageDownloadView(PathDownloadView):
"""Serve a file using storage and filename."""
storage = DefaultStorage()
path = None
"""Storage the file to serve belongs to."""
path = None # Override docstring.
"""Path to the file to serve relative to storage."""
def get_path(self):
"""Return path of the file to serve, relative to storage.
Default implementation simply returns view's :py:attr:`path`.
Override this method if you want custom implementation.
"""
return super(StorageDownloadView, self).get_path()
def get_file(self):
"""Use path and storage to return wrapper around file to serve."""
return self.storage.open(self.get_path())
class VirtualDownloadView():

View file

@ -23,6 +23,17 @@ Two main use cases:
override :py:meth:`django_downloadview.views.PathDownloadView:get_path`.
*******************
StorageDownloadView
*******************
The :py:class:`django_downloadview.views.StorageDownloadView` class-based view
allows you to **serve files given a storage and a path**.
Use this view when you manage files in a storage (which is a good practice),
unrelated to a model.
******************
ObjectDownloadView
******************