Django: difference between MEDIA_ROOT and STATIC_ROOT
DoriDoro
Posted on July 10, 2024
Introduction
STATIC_ROOT
vs. MEDIA_ROOT
In web development, particularly when working with Django, managing assets such as images, videos, CSS, and JavaScript files is a critical component of building a robust and efficient web application. Two key settings in Django, MEDIA_ROOT
and STATIC_ROOT
, that often cause confusion among developers, especially those new to the framework. Despite their seemingly similar roles in handling files, these settings serve distinct purposes and are configured differently within a Django project. Understanding the differences between MEDIA_ROOT
and STATIC_ROOT
is essential for organizing and deploying your web application's static and media content effectively. In this discussion, we will delve into the definitions, uses, and distinctions of MEDIA_ROOT
and STATIC_ROOT
, providing clarity on how each contributes to the file management strategy of a Django project.
-
STATIC_ROOT
:-
Purpose: It is the directory where all static files are collected (using the
collectstatic
management command:python manage.py collectstatic
) for deployment. - Use Case: Static files are typically assets like CSS, JavaScript, and images that are part of your application's front-end and do not change frequently.
- Settings:
STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
-
Purpose: It is the directory where all static files are collected (using the
-
MEDIA_ROOT
:- Purpose: It is the directory where user-uploaded files are stored. This includes files uploaded via forms, such as profile pictures or documents.
- Use Case: Media files are usually content that can change, such as user uploads or files generated by the application.
- Settings:
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Key Differences
-
Nature of Files:
-
STATIC_ROOT
: Contains static assets that are part of your codebase and are typically versioned with your application. -
MEDIA_ROOT
: Contains media files uploaded by users or dynamically generated by the application.
-
-
File Management:
-
STATIC_ROOT
: Files are collected here during deployment usingcollectstatic
. -
MEDIA_ROOT
: Files are stored directly when uploaded, without needing a collection step.
-
-
URL Serving:
-
STATIC_URL
: URL prefix for accessing static files. -
MEDIA_URL
: URL prefix for accessing media files.
-
-
Access Control:
-
STATIC_ROOT
: Usually public and accessible to all users. -
MEDIA_ROOT
: Access can be restricted and managed more granularly depending on the application needs.
-
Using upload_to
with MEDIA_ROOT
When you specify upload_to
in a model field, it creates a subdirectory in the MEDIA_ROOT
where the file will be stored.
Example with Model
#models.py
from django.db import models
class Picture(models.Model):
photo = models.ImageField(upload_to='images/')
Settings Example
Here’s an example of how you might set up MEDIA_ROOT
in your settings.py
:
# settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
In this setup:
-
MEDIA_ROOT
points to themedia
directory in your project’s base directory. -
upload_to='images/'
means the file will be saved inmedia/images/
.
How it Works with File Uploads
Saving a File:
When a user uploads a file, Django will save it in theMEDIA_ROOT
directory, under the subdirectory specified byupload_to
.Path Example:
If a file namedexample.jpg
is uploaded through a model field withupload_to='images/'
, the file path would be:
media/images/example.jpg
Serving Media Files
In development, Django can serve media files using the following settings in your urls.py
:
# urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# Your URL patterns...
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
In production, you typically configure your web server (e.g., Nginx or Apache) to serve files from MEDIA_ROOT
.
Recommended Structure
It’s typically recommended to separate media files from static files:
-
Static Files:
- Directory:
static/
- Path:
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
- Directory:
-
Media Files:
- Directory:
media/
- Path:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
- Directory:
This helps maintain a clean and manageable structure for your project’s file assets.
Directory Structure Example
# project tree
myproject/
│
├── static/
│ └── staticfiles/ # Collected static files (after running `collectstatic`)
│
├── media/
│ └── images/ # Uploaded media files (via `MEDIA_ROOT`)
│
├── manage.py
├── myproject/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
|
├── app/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── views.py
│ └── templates/
│ └── projects.html
Example Model with Media Files
Assuming you have the following models:
# models.py
from django.db import models
class Project(models.Model):
title = models.CharField(max_length=200)
category = models.CharField(max_length=100)
# Other fields...
class Picture(models.Model):
project = models.ForeignKey(Project, related_name='pictures', on_delete=models.CASCADE)
photo = models.ImageField(upload_to='images/')
description = models.TextField()
# Other fields...
Create a Class-Based-View (CBV) for the template
#views.py
from django.views.generic import ListView
from app.models import Project
class PortfolioView(ListView):
model = Project
template_name = "app/projects.html" # default Django name: project_list.html
context_object_name = "projects"
Using the Template to Display Media Files
Here’s how you can update your template to display the media files:
# projects.html
{% for project in projects %}
<div>
<h4>{{ project.title }}</h4>
<p>{{ project.category }}</p>
{% for picture in project.pictures.all %}
<img src="{{ picture.photo.url }}" alt="{{ project.title }}">
{% endfor %}
</div>
{% endfor %}
In this setup:
- You access the media file URL in the template using
{{ picture.photo.url }}
, which Django handles based on theMEDIA_URL
.
Final Considerations
-
Development vs. Production:
- During development, Django can serve static and media files directly.
- In production, it’s recommended to use a web server (like Nginx or Apache) to serve static and media files.
-
Security:
- Ensure that media files are served securely, especially if they contain sensitive information.
- You may need to set appropriate permissions and access controls based on your application’s requirements.
By following these guidelines, you can efficiently manage and serve static and media files in your Django project.
Posted on July 10, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.