Make your own view


The django_downloadview.views.DownloadMixin class is not a view. It is a base class which you can inherit of to create custom download views.

DownloadMixin is a base of BaseDownloadView, which itself is a base of all other django_downloadview’s builtin views.

class django_downloadview.views.base.DownloadMixin

Bases: object

Placeholders and base implementation to create file download views.


This class does not inherit from django.views.generic.base.View.

The get_file() method is a placeholder subclasses must implement. Base implementation raises NotImplementedError.

Other methods provide a base implementation that use the file wrapper returned by get_file().


Response class, to be used in render_to_response().

alias of DownloadResponse

attachment = True

Whether to return the response as attachment or not.

When True (the default), the view returns file “as attachment”, which usually triggers a “Save the file as ...” prompt.

When False, the view returns file “inline”, as if it was an element of the current page.


The actual behaviour client-side depends on the browser and its configuration.

In fact, affects the “Content-Disposition” header via response's attachment attribute.

basename = None

Client-side filename, if only file is returned as attachment.

mimetype = None

File’s mime type. If None (the default), then the file’s mime type will be guessed via mimetypes.

encoding = None

File’s encoding. If None (the default), then the file’s encoding will be guessed via mimetypes.


Return a file wrapper instance.

Raises FileNotFound if file does not exist.


Return basename.

Override this method if you need more dynamic basename.


Return mimetype.

Override this method if you need more dynamic mime type.


Return encoding.

Override this method if you need more dynamic encoding.

was_modified_since(file_instance, since)

Return True if file_instance was modified after since.

Uses file wrapper’s was_modified_since if available, with value of since as positional argument.

Else, fallbacks to default implementation, which uses django.views.static.was_modified_since().

Django’s was_modified_since function needs a datetime and a size. It is passed modified_time and size attributes from file wrapper. If file wrapper does not support these attributes (AttributeError or NotImplementedError is raised), then the file is considered as modified and True is returned.

not_modified_response(*response_args, **response_kwargs)

Return django.http.HttpResponseNotModified instance.

download_response(*response_args, **response_kwargs)

Return DownloadResponse.


Raise Http404.

render_to_response(*response_args, **response_kwargs)

Return “download” response (if everything is ok).

Return file_not_found_response() if file does not exist.

Respects the “HTTP_IF_MODIFIED_SINCE” header if any. In that case, uses was_modified_since() and not_modified_response().

Else, uses download_response() to return a download response.


The django_downloadview.views.BaseDownloadView class is a base class to create download views. It inherits DownloadMixin and django.views.generic.base.View.

The only thing it does is to implement get: it triggers DownloadMixin's render_to_response.

class django_downloadview.views.base.BaseDownloadView(**kwargs)

Bases: django_downloadview.views.base.DownloadMixin, django.views.generic.base.View

A base DownloadMixin that implements get().

get(request, *args, **kwargs)

Handle GET requests: stream a file.

Serving a file inline rather than as attachment

Use attachment to make a view serve a file inline rather than as attachment, i.e. to display the file as if it was an internal part of a page rather than triggering “Save file as...” prompt.

See details in attachment API documentation.

from django_downloadview import ObjectDownloadView

from demoproject.object.models import Document

#: Serve ``file`` attribute of ``Document`` model, inline (not as attachment).
inline_file_view = ObjectDownloadView.as_view(

Handling http not modified responses

Sometimes, you know the latest date and time the content was generated at, and you know a new request would generate exactly the same content. In such a case, you should implement was_modified_since() in your view.


Default was_modified_since() implementation trusts file wrapper’s was_modified_since if any. Else (if calling was_modified_since() raises NotImplementedError or AttributeError) it returns True, i.e. it assumes the file was modified.

As an example, the download views above always generate “Hello world!”... so, if the client already downloaded it, we can safely return some HTTP “304 Not Modified” response:

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!", name='hello-world.txt')

    def was_modified_since(self, file_instance, since):
        return False  # Never modified, always u"Hello world!".