Static and Media Files

Back

Loading concept...

Django Static & Media Files: Your Digital Library & Photo Album πŸ“šπŸ“Έ


The Big Picture: A Library Analogy

Imagine your Django website is like a library.

  • Static files = The books, posters, and decorations that came WITH the library when it opened. They never change. The same poster stays on the wall forever.
  • Media files = The photo album where visitors can ADD their own pictures. Users upload photos, documents, and files that grow over time.

This guide will teach you EVERYTHING about managing both!


πŸ›οΈ Part 1: Static Files Overview

What Are Static Files?

Static files are the permanent decorations of your website:

  • CSS (how things look)
  • JavaScript (how things move and interact)
  • Images (logos, icons, backgrounds)
  • Fonts (how text appears)

Simple Example:

# Your website's logo
# Located at: myapp/static/images/logo.png

# Your CSS styles
# Located at: myapp/static/css/style.css

# Your JavaScript
# Located at: myapp/static/js/app.js

Why β€œStatic”?

Because these files don’t change based on who visits. Everyone sees the SAME logo, SAME stylesheet, SAME JavaScript.

Think of it like this:

  • When you visit a store, the store’s sign is STATIC - same for everyone
  • But your shopping cart is DYNAMIC - different for each person

βš™οΈ Part 2: Static Files Settings

The Settings You Need

In your settings.py, you’ll set up WHERE Django looks for static files:

# settings.py

# URL path to access static files in browser
STATIC_URL = '/static/'

# Where Django collects all static files
# for production deployment
STATIC_ROOT = BASE_DIR / 'staticfiles'

# Extra places to look for static files
STATICFILES_DIRS = [
    BASE_DIR / 'static',
]

What Each Setting Does

Setting Purpose Example
STATIC_URL URL prefix in browser /static/ makes example.com/static/css/style.css
STATIC_ROOT Folder for collected files Used in production
STATICFILES_DIRS Extra folders to search Project-wide static files

Real-World Analogy:

  • STATIC_URL = The section sign in the library (β€œFICTION →”)
  • STATIC_ROOT = The main shelf where ALL books go
  • STATICFILES_DIRS = Additional book carts around the library

🧹 Part 3: The collectstatic Command

The Great Gathering

When you’re ready to deploy (go live), Django needs to gather ALL static files into ONE place.

python manage.py collectstatic

What Happens:

graph TD A["App 1 Static Files"] --> D["collectstatic"] B["App 2 Static Files"] --> D C["Project Static Files"] --> D D --> E["STATIC_ROOT Folder"] E --> F["Ready for Production!"]

Why Do This?

In development, Django finds files from multiple places. But in production, your web server (like Nginx) needs ONE folder.

Example Output:

$ python manage.py collectstatic

128 static files copied to '/home/mysite/staticfiles'.

Think of it like: Before a big party, you gather ALL the decorations from different rooms into ONE box. Much easier for the party planner to find everything!


🚚 Part 4: Serving Static Files

Development vs Production

Development (DEBUG=True): Django serves static files automatically through django.contrib.staticfiles.

# urls.py (development only)
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... your urls
]

if settings.DEBUG:
    urlpatterns += static(
        settings.STATIC_URL,
        document_root=settings.STATIC_ROOT
    )

Production (DEBUG=False): A dedicated web server handles static files:

# Nginx configuration example
location /static/ {
    alias /home/mysite/staticfiles/;
}

Using Static Files in Templates

{% load static %}

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet"
          href="{% static 'css/style.css' %}">
</head>
<body>
    <img src="{% static 'images/logo.png' %}"
         alt="Logo">
    <script src="{% static 'js/app.js' %}">
    </script>
</body>
</html>

The {% static %} tag automatically creates the correct URL!


πŸ“Έ Part 5: Media Files Overview

What Are Media Files?

Media files are user-uploaded content:

  • Profile pictures
  • Document uploads
  • Video submissions
  • Any file a USER adds to your site

Key Difference:

Static Files Media Files
Created by developers Created by users
Never change Constantly growing
Part of code NOT part of code
Safe to include in git NEVER put in git

Real-World Example:

  • Instagram: The app’s logo = STATIC
  • Instagram: Your vacation photos = MEDIA

βš™οΈ Part 6: Media Files Settings

The Settings You Need

# settings.py

# URL path to access media files
MEDIA_URL = '/media/'

# Folder where uploaded files are saved
MEDIA_ROOT = BASE_DIR / 'media'

Setting Up URLs

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

urlpatterns = [
    # ... your urls
]

# Serve media files in development
if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL,
        document_root=settings.MEDIA_ROOT
    )

Folder Structure After Setup:

myproject/
β”œβ”€β”€ media/           ← User uploads go here
β”‚   β”œβ”€β”€ avatars/
β”‚   β”‚   └── user1.jpg
β”‚   └── documents/
β”‚       └── report.pdf
β”œβ”€β”€ static/          ← Developer files
β”‚   β”œβ”€β”€ css/
β”‚   └── js/
└── manage.py

πŸ“€ Part 7: File Uploads

Creating an Upload Form

Step 1: The Model

# models.py
from django.db import models

class UserProfile(models.Model):
    name = models.CharField(max_length=100)
    avatar = models.ImageField(
        upload_to='avatars/'
    )
    resume = models.FileField(
        upload_to='resumes/'
    )

Step 2: The Form

# forms.py
from django import forms
from .models import UserProfile

class ProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['name', 'avatar', 'resume']

Step 3: The Template

<form method="POST"
      enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Upload</button>
</form>

⚠️ CRITICAL: The enctype="multipart/form-data" is REQUIRED for file uploads!

The upload_to Parameter

# Static path
avatar = models.ImageField(upload_to='avatars/')
# Result: media/avatars/photo.jpg

# Dynamic path with function
def user_directory_path(instance, filename):
    return f'user_{instance.user.id}/{filename}'

avatar = models.ImageField(
    upload_to=user_directory_path
)
# Result: media/user_5/photo.jpg

🎯 Part 8: Handling Uploaded Files

In Your View

# views.py
from django.shortcuts import render, redirect
from .forms import ProfileForm

def upload_profile(request):
    if request.method == 'POST':
        form = ProfileForm(
            request.POST,
            request.FILES  # Don't forget this!
        )
        if form.is_valid():
            form.save()
            return redirect('success')
    else:
        form = ProfileForm()

    return render(request,
                  'upload.html',
                  {'form': form})

Accessing Uploaded Files

# In a view or template
profile = UserProfile.objects.get(id=1)

# Get the URL (for displaying)
image_url = profile.avatar.url
# Returns: /media/avatars/photo.jpg

# Get the file path (for processing)
file_path = profile.avatar.path
# Returns: /home/mysite/media/avatars/photo.jpg

# Get the filename
filename = profile.avatar.name
# Returns: avatars/photo.jpg

In Templates

{% if profile.avatar %}
    <img src="{{ profile.avatar.url }}"
         alt="Profile Picture">
{% endif %}

{% if profile.resume %}
    <a href="{{ profile.resume.url }}">
        Download Resume
    </a>
{% endif %}

File Validation

# forms.py
from django.core.validators import (
    FileExtensionValidator
)

class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ['file']

    def clean_file(self):
        file = self.cleaned_data['file']

        # Check file size (5MB limit)
        if file.size > 5 * 1024 * 1024:
            raise forms.ValidationError(
                "File too large! Max 5MB."
            )

        return file

πŸŽ“ Quick Summary

graph TD A["Django Files"] --> B["Static Files"] A --> C["Media Files"] B --> D["CSS, JS, Images"] B --> E["Developer Created"] B --> F["collectstatic"] C --> G["User Uploads"] C --> H["Dynamic Content"] C --> I["FileField/ImageField"]

The Golden Rules

  1. Static = Developer stuff (CSS, JS, logos)
  2. Media = User stuff (uploads, avatars)
  3. Always use {% static %} tag for static files
  4. Always use .url attribute for media files
  5. Never put media files in git!
  6. Always set enctype="multipart/form-data" for upload forms

πŸš€ You Did It!

You now understand:

  • βœ… What static and media files are
  • βœ… How to configure both in settings
  • βœ… The magic of collectstatic
  • βœ… Serving files in dev and production
  • βœ… Creating file upload forms
  • βœ… Handling uploaded files in views

Your Django app is ready to handle files like a pro! πŸŽ‰

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.