Static files
Static files are the files your site sends exactly as they are: CSS, JavaScript, images, fonts. Django needs to know where they live and what URL to serve them from.
Where static files go
Like templates, static files live in each app, in a folder namespaced with the app's name:
courses/
static/
courses/
css/course.css
img/badge.pngFiles shared by the whole site go in a top-level folder, which you list in the settings:
STATIC_URL = "static/" # the URL prefix for static files
STATICFILES_DIRS = [BASE_DIR / "static"] # extra folders to search, besides each app's static/
STATIC_ROOT = BASE_DIR / "staticfiles" # where collectstatic copies everything, for deploymentdjango.contrib.staticfiles must be in INSTALLED_APPS, as it is in every new project.
Linking to static files
import django
from django.conf import settings
settings.configure(
STATIC_URL="/static/",
TEMPLATES=[{"BACKEND": "django.template.backends.django.DjangoTemplates"}],
)
django.setup()
from django.template import Context, Template
t = Template("""{% load static %}<link rel="stylesheet" href="{% static 'courses/css/course.css' %}">
<img src="{% static 'courses/img/badge.png' %}" alt="Badge">""")
print(t.render(Context())){% load static %}, at the top of the template, makes the tag available, and {% static 'path' %} turns a path into a full URL. Never hard-code /static/... in templates: when the files move to a CDN or get versioned names at deployment, the tag updates every link for you.
In development
With DEBUG = True, the runserver command serves static files automatically. Create the file, refresh the page, done.
In production: collectstatic
A production web server shouldn't ask Django for every image. Before deploying, gather every app's static files into one folder:
python manage.py collectstatic1240 static files copied to '/srv/codemirai/staticfiles'.The web server (Nginx, or a CDN) then serves STATIC_ROOT directly. A popular simpler option is the WhiteNoise package, which lets Django serve its own static files efficiently, with caching headers and compression, and needs only a line of middleware.
Media files: uploads
Files uploaded by users, like profile pictures, are called media and are kept separate from your own static files:
MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media"class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(upload_to="avatars/", blank=True)In a template, {{ profile.avatar.url }} gives the file's URL. Keep the two apart: static files are part of your code and change when you deploy; media files are data that changes whenever users upload something.