[Fixed]-How does Django serve media files?

14đź‘Ť

âś…

Serving static content from Django is discouraged from the developer themselves (if I’m not wrong, it only works when in debug mode). You should use a dedicated web server, instead.

If you really need to do that, anyway, read the documentation on how to serve static files.

👤friol

14đź‘Ť

FOR DEVELOPMENT ONLY

You can setup a static media server for use with their development server by doing this in your urls.py file. I have attached the code showing how I use it (along with the forced DEBUG conditionals.)

from django.conf import settings
from django.conf.urls.defaults import *      

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('', 
    (r'^$', 'views.index'),            

    # Accounts
    (r'^accounts/login/$', 'views.user_login'),
    (r'^accounts/logout/$', 'views.user_logout'),

    # Contrib Modules
    (r'^admin/(.*)', admin.site.root),
)

if settings.DEBUG :
    urlpatterns += patterns('',
        (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
    )

I place my MEDIA_ROOT in a subdirectory of html/media and link to it as such in settings.py

MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'html/media/').replace('\\','/')

After development is finished, the project gets deployed to the web server where static media files are then served by Apache using directives.

👤Astra

8đź‘Ť

You can just add those lines to your urls.py

from django.urls import re_path
from django.views.static import serve

urlpatterns = [
    ...
    re_path(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}), 
    ]

6đź‘Ť

This is the correct way of showing image files with ImageField. Imagine we have a user profile picture:

models.py:

UserProfile:
    profilePic= models.ImageField( upload_to='PATH_TO_UPLOAD', blank=True, null=True)

settings.py:

MEDIA_ROOT = 'FULL_PATH_OF_MEDIA'
MEDIA_URL = 'URL_OF_MEDIA'

urls.py:

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

PATH_TO_UPLOAD is the path which user upload data goes. This is sub-directory of FULL_PATH_OF_MEDIA, which means the uploaded file will have

FULL_PATH_OF_MEDIA/PATH_TO_UPLOAD 

full path.Now this content can be accessed at this url:

SITE_NAME/URL_OF_MEDIA/PATH_TO_UPLOAD

I also recommend reading this on static_files vs media_files

doc

1đź‘Ť

I suspect you are getting the Django 404 page. Try directly accessing one of your images and see if that’s happening.

If so, your need to configure your web server to not send requests within your media hierarchy to Django but to instead serve them directly. Here is a snip from my Apache conf file. The first section tells Apache to send everything to Django. The second section has “SetHandler None” which says “handle stuff under /media in the normal way.”

See http://docs.djangoproject.com/en/dev/howto/deployment/modpython/ for all the exciting details.

Partial httpd.conf file for PrinceOfPinot.com (AKA pop):

<Location "/">
    SetHandler python-program
    PythonAutoReload Off
    PythonDebug Off
    PythonPath "['/var/www/production/pop', '/usr/local/lib/python2.5/site-packages/django'] + sys.path"
    SetEnv DJANGO_SETTINGS_MODULE settings
    PythonHandler django.core.handlers.modpython
</Location>

<Location "/media">
    SetHandler None
    AddOutputFilterByType DEFLATE text/html text/css application/x-javascript
</Location>
👤Peter Rowell

1đź‘Ť

I’m aware that the original question is with the dev server, but for anyone else who is looking for a production environment answer:

https://docs.djangoproject.com/en/1.8/howto/static-files/deployment/ provides a guide on how to have django serve files in a production environment. From the tone of the guide, it does seem to imply that it is best to have a separate web server to handle the files or use mod_wsgi with Apache

👤Clocker

Leave a comment