Skip to content

Commit

Permalink
Refs jazzband#23 - Implemented and tested StorageDownloadView. This S…
Browse files Browse the repository at this point in the history
…torageDownloadView is to replace an use case of former DownloadView.
  • Loading branch information
benoitbryon committed Feb 6, 2013
1 parent 5c91a53 commit e94054b
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 11 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG
Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions README
@@ -1,5 +1,5 @@
###################
Django-DownloadView
django-downloadview
###################

Django-DownloadView provides (class-based) generic download views for Django.
Expand All @@ -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.

Expand Down
12 changes: 11 additions & 1 deletion demo/demoproject/download/tests.py
Expand Up @@ -49,12 +49,22 @@ def test_download_hello_world(self):
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()
Expand Down
12 changes: 8 additions & 4 deletions demo/demoproject/download/urls.py
Expand Up @@ -5,15 +5,19 @@

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',
name='hello_world'),
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'),
)
13 changes: 12 additions & 1 deletion demo/demoproject/download/views.py
Expand Up @@ -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

Expand All @@ -18,6 +21,9 @@
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.

Expand Down Expand Up @@ -50,5 +56,10 @@ def get_path(self):
"""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."""
3 changes: 3 additions & 0 deletions demo/demoproject/templates/home.html
Expand Up @@ -13,6 +13,9 @@ <h1>Welcome to django-downloadview demo!</h1>
<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>
Expand Down
21 changes: 19 additions & 2 deletions django_downloadview/views.py
Expand Up @@ -98,10 +98,27 @@ def get_file(self):
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():
Expand Down
11 changes: 11 additions & 0 deletions docs/views.txt
Expand Up @@ -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
******************
Expand Down

0 comments on commit e94054b

Please sign in to comment.