Django MEDIA_URL and MEDIA_ROOT

I'm trying to upload an image via the Django admin and then view that image either in a page on the frontend or just via a URL.

Note this is all on my local machine.

My settings are as follows:

MEDIA_ROOT = '/home/dan/mysite/media/'

MEDIA_URL = '/media/'

I have set the upload_to parameter to 'images' and the file has been correctly uploaded to the directory:

'/home/dan/mysite/media/images/myimage.png'

However, when I try to access the image at the following URL:

http://127.0.0.1:8000/media/images/myimage.png

I get a 404 error.

Do I need to setup specific URLconf patters for uploaded media?

Any advice appreciated.

Thanks.


UPDATE for Django >= 1.7

Per Django 2.1 documentation: Serving files uploaded by a user during development

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

You no longer need if settings.DEBUG as Django will handle ensuring this is only used in Debug mode.


ORIGINAL answer for Django <= 1.6

Try putting this into your urls.py

from django.conf import settings

# ... your normal urlpatterns here

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

With this you can serve the static media from Django when DEBUG = True (when you run on local computer) but you can let your web server configuration serve static media when you go to production and DEBUG = False


Please read the official Django DOC carefully and you will find the most fit answer.

The best and easist way to solve this is like below.

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

For Django 1.9, you need to add the following code as per the documentation :

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)

For more info, you can refer here : https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development


Here What i did in Django 2.0. Set First MEDIA_ROOT an MEDIA_URL in setting.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'data/') # 'data' is my media folder
MEDIA_URL = '/media/'

Then Enable the media context_processors in TEMPLATE_CONTEXT_PROCESSORS by adding

TEMPLATES = [
{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            #here add your context Processors
            'django.template.context_processors.media',
        ],
    },
},
]

Your media context processor is enabled, Now every RequestContext will contain a variable MEDIA_URL.

Now you can access this in your template_name.html

<p><img src="{{ MEDIA_URL }}/image_001.jpeg"/></p>

Do I need to setup specific URLconf patters for uploaded media?

Yes. For development, it's as easy as adding this to your URLconf:

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

However, for production, you'll want to serve the media using Apache, lighttpd, nginx, or your preferred web server.