skip to Main Content

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

Answers


  1. 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

    Login or Signup to reply.
  2. 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
            ),
        ]
    
    
    Login or Signup to reply.
  3. 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/'
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search