PathDownloadView¶
PathDownloadView serves file given a path on local filesystem.
Use this view whenever you just have a path, outside storage or model.
Warning
Take care of path validation, especially if you compute paths from user input: an attacker may be able to download files from arbitrary locations. In most cases, you should consider managing files in storages, because they implement default security mechanisms.
Simple example¶
Setup a view to stream files given path:
import os
from django_downloadview import PathDownloadView
# Let's initialize some fixtures.
app_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.dirname(app_dir)
fixtures_dir = os.path.join(project_dir, "fixtures")
#: Path to a text file that says 'Hello world!'.
hello_world_path = os.path.join(fixtures_dir, "hello-world.txt")
#: Serve ``fixtures/hello-world.txt`` file.
static_path = PathDownloadView.as_view(path=hello_world_path)
Base options¶
PathDownloadView inherits from
DownloadMixin, which has various
options such as basename
or attachment.
Computing path dynamically¶
Override the PathDownloadView.get_path() method to adapt path
resolution to your needs:
import os
from django_downloadview import PathDownloadView
# Let's initialize some fixtures.
app_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.dirname(app_dir)
fixtures_dir = os.path.join(project_dir, "fixtures")
#: Path to a text file that says 'Hello world!'.
class DynamicPathDownloadView(PathDownloadView):
"""Serve file in ``settings.MEDIA_ROOT``.
.. warning::
Make sure to prevent "../" in path via URL patterns.
.. note::
This particular setup would be easier to perform with
:class:`StorageDownloadView`
"""
def get_path(self):
"""Return path inside fixtures directory."""
# Get path from URL resolvers or as_view kwarg.
relative_path = super().get_path()
# Make it absolute.
absolute_path = os.path.join(fixtures_dir, relative_path)
return absolute_path
dynamic_path = DynamicPathDownloadView.as_view()
The view accepts a path argument you can setup either in as_view or
via URLconfs:
from django.urls import path, re_path
from demoproject.path import views
app_name = "path"
urlpatterns = [
path("static-path/", views.static_path, name="static_path"),
re_path(
r"^dynamic-path/(?P<path>[a-zA-Z0-9_-]+\.[a-zA-Z0-9]{1,4})$",
views.dynamic_path,
name="dynamic_path",
),
]
API reference¶
- class django_downloadview.views.path.PathDownloadView(**kwargs)¶
Bases:
BaseDownloadViewServe a file using filename.
- path = None¶
Server-side name (including path) of the file to serve.
Filename is supposed to be an absolute filename of a file located on the local filesystem.
- path_url_kwarg = 'path'¶
Name of the URL argument that contains path.
- get_path()¶
Return actual path of the file to serve.
Default implementation simply returns view’s
path.Override this method if you want custom implementation. As an example,
pathcould be relative and your customget_path()implementation makes it absolute.
- get_file()¶
Use path to return wrapper around file to serve.