OverIQ.com

Handling Media Files in Django

Last updated on July 27, 2020


In Django, files which are uploaded by the user are called Media Files. Here are some examples of media files:

  • A user uploaded image, pdf, ppt etc.
  • Images of products in an e-commerce site.
  • Profile image. and so on

Just as with static files, to serve media files we have to add some configurations in our settings.py file.

Media Files Configurations #

Media files depend upon two configurations:

  1. MEDIA_ROOT
  2. MEDIA_URL

None of these variables are set by default.

MEDIA_ROOT Setting #

It contains the absolute path to the file system where Media files will be uploaded. It accepts a string, not a list or tuple.

Create a new directory named media inside Django project root directory (djangobin/django_project), the same place where manage.py is located.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
django_project/
├── db.sqlite3
├── djangobin
├── django_project
├── manage.py
├── media           <------------
├── staticfiles
└── templates

5 directories, 2 files

Open settings.py file and add the following code to the end of the file, just below STATIC_ROOT setting which we had set earlier.

djangobin/django_project/django_project/settings.py

1
2
3
4
#...
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfies')

MEDIA_ROOT  = os.path.join(BASE_DIR, 'media')

MEDIA_URL Setting #

This setting works similar to STATIC_URL and is used to access media files. Just below the MEDIA_ROOT variable, define MEDIA_ROOT variable as follows:

djangobin/django_project/django_project/settings.py

1
2
3
4
#...
MEDIA_ROOT  = os.path.join(BASE_DIR, 'media')

MEDIA_URL = '/media/'

Download this image and save it as python.png in the media directory. To access the file visit http://127.0.0.1:8000/media/python.png. You will get an HTTP 404 error like this:

But why?

The problem is that Django development server doesn't serve media files by default. To make Django development server serve static we have to add a URL pattern in sitewide urls.py file.

Open urls.py in the Django project configuration directory (djangobin/django_project/django_project) and update it as follows:

djangobin/django_project/django_project/urls.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    url(r'^', include('djangobin.urls', namespace='djangobin')),
    url(r'^admin/', admin.site.urls),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Now visit http://127.0.0.1:8000/media/python.png again, this time you should be able to see the image.

Just as with static files, in the production, you should always use a real web server to serve media files. Unfortunately, our project doesn't depend on media files. However, with the directory structure laid out, it doesn't take much to implement features which require media files. As a challenge, after going through this series try implementing such features on your own.