Opened 4 years ago

Last modified 4 years ago

#18655 new New feature

Media files should be served using file storage API

Reported by: Mitar Owned by: nobody
Component: File uploads/storage Version: 1.4
Severity: Normal Keywords:
Cc: mmitar@…, jason@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently static and media files using django.views.static.serve directly access given path for serving files, for example settings.MEDIA_ROOT. Much better would be that it would use storage API, so it could be used to serve in development also files from other storage classes, if Django is defined as such.

One such serve function I wrote:

def serve(request, path):
    """
    Serve files from default storage.
    """

    if not settings.DEBUG:
        raise exceptions.ImproperlyConfigured("The view can only be used in debug mode.")
    normalized_path = posixpath.normpath(urllib.unquote(path)).lstrip('/')

    if not storage.default_storage.exists(normalized_path):
        if path.endswith('/') or path == '':
            raise http.Http404("Directory indexes are not allowed here.")
        raise http.Http404("'%s' could not be found" % path)

    try:
        mimetype = storage.default_storage.mimetype(normalized_path) or 'application/octet-stream'
    except (NotImplementedError, AttributeError):
        mimetype = 'application/octet-stream'

    try:
        modified_time = time.mktime(storage.default_storage.modified_time(normalized_path).timetuple())
    except (NotImplementedError, AttributeError):
        modified_time = None

    size = storage.default_storage.size(normalized_path)

    if modified_time is not None and not static.was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'), modified_time, size):
        return http.HttpResponseNotModified(mimetype=mimetype)

    f = storage.default_storage.open(normalized_path, 'rb')
    try:
        response = http.HttpResponse(f.read(), mimetype=mimetype)
    finally:
        f.close()

    response['Content-Length'] = size

    if modified_time is not None:
        response['Last-Modified'] = http_utils.http_date(modified_time)

    return response  

Change History (3)

comment:1 Changed 4 years ago by Jason Mayfield

Cc: jason@… added
Triage Stage: UnreviewedDesign decision needed

comment:2 Changed 4 years ago by Aymeric Augustin

Type: UncategorizedNew feature

comment:3 Changed 4 years ago by Aymeric Augustin

Component: contrib.staticfilesFile uploads/storage
Summary: Static and media files should be served using storagesMedia files should be served using file storage API
Triage Stage: Design decision neededAccepted

For static files:

  • it's already done when django.contrib.staticfiles is enabled
  • I don't see how it would be possible when it isn't: static files are just whatever's under STATIC_ROOT

For media files:

  • it could be a good idea.

I'm restricting the scope of this ticket to media files, please provide a patch so we can better evaluate your idea.

Note: See TracTickets for help on using tickets.
Back to Top