first comit
This commit is contained in:
122
venv/lib/python3.10/site-packages/django/views/static.py
Executable file
122
venv/lib/python3.10/site-packages/django/views/static.py
Executable file
@@ -0,0 +1,122 @@
|
||||
"""
|
||||
Views and functions for serving static files. These are only to be used
|
||||
during development, and SHOULD NOT be used in a production setting.
|
||||
"""
|
||||
|
||||
import mimetypes
|
||||
import posixpath
|
||||
from pathlib import Path
|
||||
|
||||
from django.http import FileResponse, Http404, HttpResponse, HttpResponseNotModified
|
||||
from django.template import Context, Engine, TemplateDoesNotExist, loader
|
||||
from django.utils._os import safe_join
|
||||
from django.utils.http import http_date, parse_http_date
|
||||
from django.utils.translation import gettext as _
|
||||
from django.utils.translation import gettext_lazy
|
||||
|
||||
|
||||
def builtin_template_path(name):
|
||||
"""
|
||||
Return a path to a builtin template.
|
||||
|
||||
Avoid calling this function at the module level or in a class-definition
|
||||
because __file__ may not exist, e.g. in frozen environments.
|
||||
"""
|
||||
return Path(__file__).parent / "templates" / name
|
||||
|
||||
|
||||
def serve(request, path, document_root=None, show_indexes=False):
|
||||
"""
|
||||
Serve static files below a given point in the directory structure.
|
||||
|
||||
To use, put a URL pattern such as::
|
||||
|
||||
from django.views.static import serve
|
||||
|
||||
path('<path:path>', serve, {'document_root': '/path/to/my/files/'})
|
||||
|
||||
in your URLconf. You must provide the ``document_root`` param. You may
|
||||
also set ``show_indexes`` to ``True`` if you'd like to serve a basic index
|
||||
of the directory. This index view will use the template hardcoded below,
|
||||
but if you'd like to override it, you can create a template called
|
||||
``static/directory_index.html``.
|
||||
"""
|
||||
path = posixpath.normpath(path).lstrip("/")
|
||||
fullpath = Path(safe_join(document_root, path))
|
||||
if fullpath.is_dir():
|
||||
if show_indexes:
|
||||
return directory_index(path, fullpath)
|
||||
raise Http404(_("Directory indexes are not allowed here."))
|
||||
if not fullpath.exists():
|
||||
raise Http404(_("“%(path)s” does not exist") % {"path": fullpath})
|
||||
# Respect the If-Modified-Since header.
|
||||
statobj = fullpath.stat()
|
||||
if not was_modified_since(
|
||||
request.META.get("HTTP_IF_MODIFIED_SINCE"), statobj.st_mtime
|
||||
):
|
||||
return HttpResponseNotModified()
|
||||
content_type, encoding = mimetypes.guess_type(str(fullpath))
|
||||
content_type = content_type or "application/octet-stream"
|
||||
response = FileResponse(fullpath.open("rb"), content_type=content_type)
|
||||
response.headers["Last-Modified"] = http_date(statobj.st_mtime)
|
||||
if encoding:
|
||||
response.headers["Content-Encoding"] = encoding
|
||||
return response
|
||||
|
||||
|
||||
# Translatable string for static directory index template title.
|
||||
template_translatable = gettext_lazy("Index of %(directory)s")
|
||||
|
||||
|
||||
def directory_index(path, fullpath):
|
||||
try:
|
||||
t = loader.select_template(
|
||||
[
|
||||
"static/directory_index.html",
|
||||
"static/directory_index",
|
||||
]
|
||||
)
|
||||
except TemplateDoesNotExist:
|
||||
with builtin_template_path("directory_index.html").open(encoding="utf-8") as fh:
|
||||
t = Engine(libraries={"i18n": "django.templatetags.i18n"}).from_string(
|
||||
fh.read()
|
||||
)
|
||||
c = Context()
|
||||
else:
|
||||
c = {}
|
||||
files = []
|
||||
for f in fullpath.iterdir():
|
||||
if not f.name.startswith("."):
|
||||
url = str(f.relative_to(fullpath))
|
||||
if f.is_dir():
|
||||
url += "/"
|
||||
files.append(url)
|
||||
c.update(
|
||||
{
|
||||
"directory": path + "/",
|
||||
"file_list": files,
|
||||
}
|
||||
)
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
|
||||
def was_modified_since(header=None, mtime=0):
|
||||
"""
|
||||
Was something modified since the user last downloaded it?
|
||||
|
||||
header
|
||||
This is the value of the If-Modified-Since header. If this is None,
|
||||
I'll just return True.
|
||||
|
||||
mtime
|
||||
This is the modification time of the item we're talking about.
|
||||
"""
|
||||
try:
|
||||
if header is None:
|
||||
raise ValueError
|
||||
header_mtime = parse_http_date(header)
|
||||
if int(mtime) > header_mtime:
|
||||
raise ValueError
|
||||
except (ValueError, OverflowError):
|
||||
return True
|
||||
return False
|
||||
Reference in New Issue
Block a user