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 there is no place reverse-proxy can load files from after Django exited.

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 django.core.files.base import ContentFile

from django_downloadview import VirtualDownloadView


class TextDownloadView(VirtualDownloadView):
    def get_file(self):
        """Return :class:`django.core.files.base.ContentFile` object."""
        return ContentFile(u"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 StringIO import StringIO

from django_downloadview import VirtualDownloadView
from django_downloadview import VirtualFile


class StringIODownloadView(VirtualDownloadView):
    def get_file(self):
        """Return wrapper on ``StringIO`` object."""
        file_obj = StringIO(u"Hello world!\n")
        return VirtualFile(file_obj, name='hello-world.txt')

Stream generated content

Let’s consider you have a generator function (yield) or an iterator object (__iter__()):

def generate_hello():
    yield u'Hello '
    yield u'world!'
    yield u'\n'

Stream generated content using VirtualDownloadView, VirtualFile and StringIteratorIO:

from django_downloadview import VirtualDownloadView
from django_downloadview import VirtualFile
from django_downloadview import StringIteratorIO


class GeneratedDownloadView(VirtualDownloadView):
    def get_file(self):
        """Return wrapper on ``StringIteratorIO`` object."""
        file_obj = StringIteratorIO(generate_hello())
        return VirtualFile(file_obj, name='hello-world.txt')

API reference

class django_downloadview.views.virtual.VirtualDownloadView(**kwargs)

Bases: django_downloadview.views.base.BaseDownloadView

Serve not-on-disk or generated-on-the-fly file.

Override the get_file() method to customize file wrapper.

was_modified_since(file_instance, since)

Delegate to file wrapper’s was_modified_since, or return True.

This is the implementation of an edge case: when files are generated on the fly, we cannot guess whether they have been modified or not. If the file wrapper implements was_modified_since() method, then we trust it. Otherwise it is safer to suppose that the file has been modified.

This behaviour prevents file size to be computed on the Django side. Because computing file size means iterating over all the file contents, and we want to avoid that whenever possible. As an example, it could reduce all the benefits of working with dynamic file generators... which is a major feature of virtual files.

Read the Docs v: 1.3
Versions
latest
1.3
1.2
1.1
1.0
Downloads
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.