serving media files in Django for Production

2.4k Views Asked by At

I want to serve all types of media files in my Django Project I used Whitenoise to server static files and static files are working well but I'm having issues with serving images that are uploaded by users (I'm using Linux shared hosting Cpanel) Directory structure

Project_name
App_1
App_2
Staticfiles (that are collected via collectstatic cmd)
manage.py
passenger_wsgi.py

and here is the project's settings.py

STATIC_ROOT = BASE_DIR / 'staticfiles'
STATIC_URL = '/static/'
MEDIA_URL = ''
STATICFILES_DIRS =[
    BASE_DIR/ 'static'
]
 MEDIA_ROOT = BASE_DIR / 'staticfiles/images'

and file urls.py

urlpatterns+=static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
3

There are 3 best solutions below

4
Yery cs On

Whitenoise only checks for static files at startup and so files added after the app starts won't be seen.

Since, Whitenose is not suitable for serving user-uploaded media files.

Please check Whitenose official docs. http://whitenoise.evans.io/en/latest/django.html#serving-media-files

0
mka On

If you want to serve media from django in production just create your own static function based on original static function like this:

#my_app/static.py

import re
from urllib.parse import urlsplit

from django.core.exceptions import ImproperlyConfigured
from django.urls import re_path
from django.views.static import serve


def static(prefix, view=serve, **kwargs):
    """
    Return a URL pattern for serving files in debug mode.
    from django.conf import settings
    from django.conf.urls.static import static
    urlpatterns = [
        # ... the rest of your URLconf goes here ...
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    """
    if not prefix:
        raise ImproperlyConfigured("Empty static prefix not permitted")
    elif urlsplit(prefix).netloc: # <- removed DEBUG from this line
        # No-op if non-local prefix.
        return []
    return [
        re_path(
            r"^%s(?P<path>.*)$" % re.escape(prefix.lstrip("/")), view, kwargs=kwargs
        ),
    ]

0
Muhammad Wahaj Murtaza On

Though it is not recommended, you can need it if you are not using ngingx/apache and have a small server. My case is I am using whitenoise and gunicorn to serve on local server.

You can serve media files by creating a view for media file.

In myapp.views.py

def media(request, file_path=None):
    from django.conf import settings as cfg
    media_root = getattr(cfg, 'MEDIA_ROOT', None)

    if not media_root:
        return HttpResponseBadRequest('Invalid Media Root Configuration')
    if not file_path:
        return HttpResponseBadRequest('Invalid File Path')

    with open(os.path.join(media_root, file_path), 'rb') as doc:
        response = HttpResponse(doc.read(), content_type='application/doc')
        response['Content-Disposition'] = 'filename=%s' % (file_path.split('/')[-1])
        return response

Now add url in app myapp.urls.py

url(r'^myapp/media/(?P<file_path>.+)+', myapp.views.media, name='media'),

in settings.py

MEDIA_ROOT = os.path.abspath(__file__ + "../../../media")
MEDIA_URL = '/myapp/media/'