← Back to Django Course | Chapter 11: Static Files & Media Handling | Lesson 3 of 8

Serving Static Files in Development

In development, Django plays delivery driver for your CSS and images itself, so you don't need a separate web server just to see your styles while you build.

Automatic Serving with runserver

When DEBUG=True, django.contrib.staticfiles automatically wires up a URL pattern so runserver can serve every static file it finds, no manual configuration needed.

Note: Just start the server and reference files with {% static %} — Django handles the rest.

Example: Automatic Serving with runserver

When DEBUG=True, django.contrib.staticfiles automatically wires up a URL pattern so runserver can serve every static file it finds, no manual configuration needed.

bash
python manage.py runserver

⚠️ Run this command in your terminal.

Adding Extra Static Directories

STATICFILES_DIRS lists additional folders (outside any single app) that should also be searched for static files, such as a project-wide static/ directory.

Example: Adding Extra Static Directories

STATICFILES_DIRS lists additional folders (outside any single app) that should also be searched for static files, such as a project-wide static/ directory.

markup
# settings.py
STATICFILES_DIRS = [
    BASE_DIR / 'static',
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Why This Doesn't Work in Production

The development server's static file serving is intentionally simple and unoptimized. In production, DEBUG is False and this auto-serving stops, so a real web server or collectstatic-backed setup is required instead.

Warning: Never set DEBUG=True in production just to keep static files working — it also exposes sensitive debug information.

Example: Why This Doesn't Work in Production

The development server's static file serving is intentionally simple and unoptimized. In production, DEBUG is False and this auto-serving stops, so a real web server or collectstatic-backed setup is required instead.

markup
# settings.py (production)
DEBUG = False
# Static files now need collectstatic + a real web server
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Relying on Django's development static file serving in production — it's slow and insecure at scale, meant only for local development.
  2. Forgetting DEBUG=True is required for runserver to auto-serve static files without extra URL configuration.
  3. Not restarting the development server after adding a new static/ directory to STATICFILES_DIRS.
Chapter Summary
  • Django's runserver automatically serves static files when DEBUG is True.
  • This convenience is not meant for production — real deployments use a web server or CDN instead.
  • STATICFILES_DIRS lets you add extra folders beyond each app's own static/ directory.
  • Static files update immediately on refresh during development, no collectstatic step needed.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.