VirtualDownloadView¶
VirtualDownloadView
serves files that do not live on disk.
Use it when you want to stream a file which content is dynamically generated
or which lives in memory.
It is all about overriding VirtualDownloadView.get_file()
method so that
it returns a suitable file wrapper…
Note
Current implementation does not support reverse-proxy optimizations, because content is actually generated within Django, not stored in some third-party place.
Base options¶
VirtualDownloadView
inherits from
DownloadMixin
, which has various
options such as basename
or attachment
.
Serve text (string or unicode) or bytes¶
Let’s consider you build text dynamically, as a bytes or string or unicode
object. Serve it with Django’s builtin
ContentFile
wrapper:
from io import StringIO
from django.core.files.base import ContentFile
class TextDownloadView(VirtualDownloadView):
def get_file(self):
"""Return :class:`django.core.files.base.ContentFile` object."""
return ContentFile(b"Hello world!\n", name="hello-world.txt")
Serve StringIO¶
StringIO
object lives in memory. Let’s wrap it in some
download view via VirtualFile
:
from io import StringIO
from django.core.files.base import ContentFile
from django_downloadview import TextIteratorIO, VirtualDownloadView, VirtualFile
class StringIODownloadView(VirtualDownloadView):
def get_file(self):
"""Return wrapper on ``six.StringIO`` object."""
file_obj = StringIO("Hello world!\n")
Stream generated content¶
Let’s consider you have a generator function (yield
) or an iterator object
(__iter__()
):
def generate_hello():
yield "Hello "
yield "world!"
Stream generated content using VirtualDownloadView
,
VirtualFile
and
BytesIteratorIO
:
from django.core.files.base import ContentFile
class GeneratedDownloadView(VirtualDownloadView):
def get_file(self):
"""Return wrapper on ``StringIteratorIO`` object."""
file_obj = TextIteratorIO(generate_hello())