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())

API reference