{"id":120253,"date":"2024-12-18T00:46:04","date_gmt":"2024-12-18T00:46:04","guid":{"rendered":"\/tutorials\/?p=120253"},"modified":"2025-09-12T14:39:06","modified_gmt":"2025-09-12T14:39:06","slug":"django-static-files","status":"publish","type":"post","link":"\/tutorials\/django-static-files","title":{"rendered":"Django static files: How to configure and serve them"},"content":{"rendered":"<p>In Django, static files are the <strong>non-dynamic assets that shape your web application&rsquo;s front end, including CSS, JavaScript, and images<\/strong>.<\/p><p>You need to manage static files carefully because Django treats them differently in development and production environments.<\/p><p>Configuring and serving Django static files involves four key stages:<\/p><ol class=\"wp-block-list\">\n<li><strong>Configuration<\/strong>. Define <strong>STATIC_URL<\/strong> and <strong>STATICFILES_DIRS<\/strong> in your <strong>settings.py<\/strong> file to tell Django where to find your assets during development.<\/li>\n\n\n\n<li><strong>Template integration<\/strong>. Use the <strong>{% static %}<\/strong> template tag to link to your assets correctly in HTML files.<\/li>\n\n\n\n<li><strong>Deployment preparation<\/strong>. For production, set a <strong>STATIC_ROOT<\/strong> and run the <strong>collectstatic<\/strong> command to gather all static files into a single directory.<\/li>\n\n\n\n<li><strong>Production serving<\/strong>. Configure a web server like Nginx to serve these collected files, and you can implement performance optimizations like caching and cache-busting with <strong>ManifestStaticFilesStorage<\/strong>.<\/li>\n<\/ol><p>\n\n\n\n\n\n\n<\/p><h2 class=\"wp-block-heading\" id=\"h-how-to-configure-static-files-in-django-settings\">How to configure static files in Django settings<\/h2><p>You configure static files in Django through the <strong>settings.py<\/strong> file. In it, you <strong>define key parameters that tell Django where to find and how to serve your assets<\/strong>.<\/p><h3 class=\"wp-block-heading\" id=\"h-setting-static-url-and-staticfiles-dirs\">Setting STATIC_URL and STATICFILES_DIRS<\/h3><p>In <strong>development<\/strong>, you mainly configure two settings: <strong>STATIC_URL<\/strong> and <strong>STATICFILES_DIRS<\/strong>.<\/p><ul class=\"wp-block-list\">\n<li><strong>STATIC_URL<\/strong> defines the URL prefix Django uses when linking to static assets.<\/li>\n\n\n\n<li><strong>STATICFILES_DIRS<\/strong> lists the directories where Django searches for project-level static files.<\/li>\n<\/ul><p>Add the following to your <strong>project_name\/settings.py<\/strong> file:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># project_name\/settings.py\n\n# URL prefix for static files.\n# Example: '\/static\/css\/style.css'\nSTATIC_URL = '\/static\/'\n\n# Additional directories Django will search for static files,\n# in addition to each app's 'static' folder.\nSTATICFILES_DIRS = [\n    BASE_DIR \/ \"static\",\n]<\/pre><h3 class=\"wp-block-heading\" id=\"h-app-specific-static-files-structure\">App-specific static files structure<\/h3><p>By default, Django looks for static files inside a <strong>static<\/strong> folder within each app directory. This approach keeps every app&rsquo;s assets organized and self-contained.<\/p><p>A good practice is to create a subdirectory inside <strong>static<\/strong> named after the app itself. Doing so prevents filename conflicts when multiple apps include assets with the same name, such as <strong>style.css<\/strong>.<\/p><p>Here&rsquo;s an example structure:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">my_app\/\n&#9500;&#9472;&#9472; __init__.py\n&#9500;&#9472;&#9472; models.py\n&#9500;&#9472;&#9472; static\/\n&#9474;   &#9492;&#9472;&#9472; my_app\/\n&#9474;       &#9500;&#9472;&#9472; style.css\n&#9474;       &#9492;&#9472;&#9472; main.js\n&#9492;&#9472;&#9472; views.py<\/pre><p>After configuring and organizing your static files, use them in your Django templates to load stylesheets, scripts, and images.<\/p><h2 class=\"wp-block-heading\" id=\"h-how-to-use-static-files-in-django-templates\">How to use static files in Django templates<\/h2><p>To use static files in <a href=\"\/tutorials\/working-with-django-templates\">Django templates<\/a>, <strong>load the static template tag library and use the {% static %} tag to generate the correct URL for each asset<\/strong>.<\/p><h3 class=\"wp-block-heading\" id=\"h-loading-the-static-tag\">Loading the {% static %} tag<\/h3><p>Place the <strong>{% load static %}<\/strong> tag at the top of any template that references static assets. This makes the <strong>{% static %}<\/strong> tag available in that template.<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{% load static %}\n&lt;!DOCTYPE html&gt;\n&lt;html&gt;<\/pre><h3 class=\"wp-block-heading\" id=\"h-examples-for-css-images-and-js\">Examples for CSS, images, and JS<\/h3><p>After loading the static tag library, link your CSS, JavaScript, and image files with the<strong> {% static %}<\/strong> tag. This tag takes the asset&rsquo;s relative path and generates the full URL based on your <strong>STATIC_URL<\/strong> setting.<\/p><p>Here&rsquo;s an example using the <strong>my_app<\/strong> structure:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{% load static %}\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;title&gt;My App&lt;\/title&gt;\n    &lt;link rel=\"stylesheet\" href=\"{% static 'my_app\/style.css' %}\"&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Welcome!&lt;\/h1&gt;\n    &lt;img src=\"{% static 'my_app\/images\/logo.png' %}\" alt=\"Logo\"&gt;\n    &lt;script src=\"{% static 'my_app\/main.js' %}\"&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre><p>The next step is to prepare your static files for deployment so Django can serve them efficiently in production.<\/p><h2 class=\"wp-block-heading\" id=\"h-preparing-static-files-for-deployment\">Preparing static files for deployment<\/h2><p>In a <strong>production<\/strong> environment where <strong>DEBUG<\/strong> is set to <strong>False<\/strong>, Django&rsquo;s development server stops serving static files.<\/p><p>Therefore, you must <strong>collect all project static assets into a single directory that your web server can access<\/strong>. The <strong>django.contrib.staticfiles<\/strong> app, included in <strong>INSTALLED_APPS<\/strong> by default, handles this process.<\/p><h3 class=\"wp-block-heading\" id=\"h-configuring-static-root\">Configuring STATIC_ROOT<\/h3><p>The <strong>STATIC_ROOT<\/strong> setting defines the directory where Django collects all static files from your project and its apps for deployment.<\/p><p>Don&rsquo;t confuse <strong>STATIC_ROOT<\/strong> with <strong>STATICFILES_DIRS<\/strong>:<\/p><ul class=\"wp-block-list\">\n<li><strong>STATICFILES_DIRS<\/strong> tells Django where to look for static files during development.<\/li>\n\n\n\n<li><strong>STATIC_ROOT<\/strong> tells Django where to place the collected files for production.<\/li>\n<\/ul><p>Add this line to your <strong>project_name\/settings.py<\/strong> file:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># project_name\/settings.py\n# Absolute path to the directory where collectstatic gathers static files for deployment.\nSTATIC_ROOT = BASE_DIR \/ \"staticfiles\"<\/pre><h3 class=\"wp-block-heading\" id=\"h-running-collectstatic\">Running collectstatic<\/h3><p>Use the <strong>python manage.py collectstatic<\/strong> command to gather all static files from your <strong>STATICFILES_DIRS<\/strong> and app directories, then copy them into the folder defined by <strong>STATIC_ROOT<\/strong>.<\/p><p>Run the following command in your terminal:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">python manage.py collectstatic<\/pre><p>Django will prompt you to confirm, then copy the files and create the <strong>staticfiles<\/strong> directory if it doesn&rsquo;t exist.<\/p><p>While <strong>collectstatic<\/strong> prepares your files for production, Django also provides built-in tools for serving static files during development.<\/p><h2 class=\"wp-block-heading\" id=\"h-how-to-serve-django-static-files-in-production\">How to serve Django static files in production<\/h2><p>In production, <strong>configure a dedicated web server such as Nginx or Apache to serve static files directly from the STATIC_ROOT directory<\/strong>.<\/p><p>This setup improves efficiency by letting your Django application server handle dynamic requests while the web server delivers static assets.<\/p><h3 class=\"wp-block-heading\" id=\"h-nginx-example-configuration\">Nginx example configuration<\/h3><p>A typical Nginx setup uses a location block to intercept requests for static files and serve them directly from the filesystem. Nginx forwards all other requests to your Django application.<\/p><p>Here&rsquo;s a basic server block configuration:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">server {\n    listen 80;\n    server_name your-domain.tld;\n\n    # Serve static files\n    location \/static\/ {\n        alias \/path\/to\/your\/project\/staticfiles\/;\n    }\n\n    # Forward requests to Django app\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:8000; # Gunicorn running on port 8000\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    }\n}<\/pre><p>In this example, Nginx serves any request starting with <strong>\/static\/<\/strong> directly from the <strong>staticfiles<\/strong> directory, while forwarding all other requests to your Django app.<\/p><h3 class=\"wp-block-heading\" id=\"h-using-a-cdn-for-django-static-files\">Using a CDN for Django static files<\/h3><p>A content delivery network (CDN) offers an even faster way to serve static assets. By delivering files from servers closer to your users, a CDN improves performance and reduces load on your application server.<\/p><p>To use a CDN:<\/p><ol class=\"wp-block-list\">\n<li>Run <strong>collectstatic<\/strong> to gather all files into the <strong>STATIC_ROOT<\/strong> directory.<\/li>\n\n\n\n<li>Upload the contents of<strong> STATIC_ROOT<\/strong> to your CDN provider&rsquo;s storage, such as Amazon S3 or Cloudflare R2.<\/li>\n\n\n\n<li>Update your <strong>settings.py<\/strong> file to point <strong>STATIC_URL<\/strong> to your CDN domain:<\/li>\n<\/ol><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># settings.py\nSTATIC_URL = \"https:\/\/your-cdn-provider.com\/static\/\"<\/pre><p>Once configured, the <strong>{% static %}<\/strong> tag generates URLs that point to your CDN, speeding up delivery of your site&rsquo;s assets.<\/p><p>With your static files served through a web server or CDN, you can optimize them further to improve loading speed and overall performance.<\/p><h2 class=\"wp-block-heading\" id=\"h-optimizing-django-static-files\">Optimizing Django static files<\/h2><p>To improve your application&rsquo;s front-end performance, <strong>add caching and file versioning to your static assets<\/strong>.<\/p><h3 class=\"wp-block-heading\" id=\"h-caching-with-headers\">Caching with headers<\/h3><p>You can tell browsers to cache your static files by adding caching headers in your web server configuration. This lets the browser store a local copy of the files for a set time, avoiding unnecessary downloads on repeat visits.<\/p><p>In Nginx, add the <strong>expires<\/strong> and <strong>add_header<\/strong> directives inside your static location block:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">location \/static\/ {\n    alias \/path\/to\/your\/project\/staticfiles\/;\n    expires 30d;\n    add_header Cache-Control \"public, no-transform\";\n}<\/pre><h3 class=\"wp-block-heading\" id=\"h-using-manifeststaticfilesstorage\">Using ManifestStaticFilesStorage<\/h3><p>Long-term browser caching creates a problem when you update a file: users may still load the old cached version. Django solves this with a technique called <strong>cache-busting<\/strong>.<\/p><p>When you enable <strong>ManifestStaticFilesStorage<\/strong>, Django renames each static file with a hash of its content during the <strong>collectstatic<\/strong> process. For example, <strong>style.css<\/strong> becomes <strong>style.a1b2c3d4.css<\/strong>.<\/p><p>Because the filename changes whenever the content does, the browser must download the new version.<\/p><p>To enable <strong>ManifestStaticFilesStorage<\/strong>, update the <strong>STORAGES<\/strong> dictionary in your <strong>settings.py<\/strong> file. This setting tells Django to use <strong>ManifestStaticFilesStorage<\/strong> for static files.<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># settings.py\nSTORAGES = {\n    \"default\": {\n        \"BACKEND\": \"django.core.files.storage.FileSystemStorage\",\n    },\n    \"staticfiles\": {\n        \"BACKEND\": \"django.contrib.staticfiles.storage.ManifestStaticFilesStorage\",\n    },\n}<\/pre><p>This configuration makes <strong>collectstatic<\/strong> rename each file by appending a hash of its content, enabling effective cache-busting. Django still uses the <strong>default<\/strong> key for general file storage operations.<\/p><p>In addition to optimizing your own assets, you&rsquo;ll often need to include third-party static libraries in your Django project.<\/p><h2 class=\"wp-block-heading\" id=\"h-integrating-third-party-static-libraries-in-django\">Integrating third-party static libraries in Django<\/h2><p>You can <strong>integrate third-party front-end libraries such as Bootstrap or jQuery into your Django project with just a few steps<\/strong>. The process works the same for any library.<\/p><ol class=\"wp-block-list\">\n<li>Download the library&rsquo;s <a href=\"https:\/\/getbootstrap.com\/docs\/5.3\/getting-started\/download\" target=\"_blank\" rel=\"noopener\">compiled CSS and JS files<\/a>.<\/li>\n\n\n\n<li>Create a folder inside your project&rsquo;s main <strong>static<\/strong> directory (the one defined in <strong>STATICFILES_DIRS<\/strong>). A common practice is to name it <strong>vendor<\/strong>.<\/li>\n\n\n\n<li>Place the library files inside this folder. For example, with Bootstrap you might have:\n<ul class=\"wp-block-list\">\n<li><strong>static\/vendor\/bootstrap\/css\/<\/strong><\/li>\n\n\n\n<li><strong>static\/vendor\/bootstrap\/js\/<\/strong><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Link to these files in your templates using the <strong>{% static %}<\/strong> tag, just as you would with your own assets:<\/li>\n<\/ol><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{% load static %}\n&lt;link rel=\"stylesheet\" href=\"{% static 'vendor\/bootstrap\/css\/bootstrap.min.css' %}\"&gt;\n&lt;script src=\"{% static 'vendor\/bootstrap\/js\/bootstrap.bundle.min.js' %}\"&gt;&lt;\/script&gt;<\/pre><figure class=\"wp-block-image size-large\"><a class=\"hgr-tutorials-cta hgr-tutorials-cta-vps-hosting\" href=\"\/vps-hosting\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" width=\"1024\" height=\"300\" src=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/2\/2023\/02\/VPS-hosting-banner.png\/public\" alt=\"\" class=\"wp-image-77934\" srcset=\"https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/2\/2023\/02\/VPS-hosting-banner.png\/w=1024,fit=scale-down 1024w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/2\/2023\/02\/VPS-hosting-banner.png\/w=300,fit=scale-down 300w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/2\/2023\/02\/VPS-hosting-banner.png\/w=150,fit=scale-down 150w, https:\/\/imagedelivery.net\/LqiWLm-3MGbYHtFuUbcBtA\/wp-content\/uploads\/sites\/2\/2023\/02\/VPS-hosting-banner.png\/w=768,fit=scale-down 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure><h2 class=\"wp-block-heading\" id=\"h-what-should-you-learn-after-configuring-django-static-files\">What should you learn after configuring Django static files?<\/h2><p>Now that you understand how to manage static assets, the next step is <strong>learning how Django handles application data and user authentication<\/strong>.<\/p><p>A key part of this is <a href=\"\/tutorials\/django-user-model\">customizing the Django user model<\/a>. Doing so lets you extend the default user schema to fit your project&rsquo;s needs.<\/p><p>Getting this structure right is crucial, since it directly affects how you implement features like user profiles, permissions, and personalized content.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Django, static files are the non-dynamic assets that shape your web application&rsquo;s front end, including CSS, JavaScript, and images. [&#8230;]<\/p>\n<p><a class=\"btn btn-secondary understrap-read-more-link\" href=\"\/tutorials\/django-static-files\">Read More&#8230;<\/a><\/p>\n","protected":false},"author":185,"featured_media":87036,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"How to configure static files in Django","rank_math_description":"Master Django static files. Follow our tutorial to configure settings, use templates, and deploy assets with NGINX for production.","rank_math_focus_keyword":"django static files","footnotes":""},"categories":[22646,22644],"tags":[],"class_list":["post-120253","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pre-installed-applications","category-vps"],"hreflangs":[{"locale":"en-US","link":"https:\/\/www.hostinger.com\/tutorials\/django-static-files","default":0},{"locale":"en-GB","link":"https:\/\/www.hostinger.com\/uk\/tutorials\/django-static-files","default":0},{"locale":"en-MY","link":"https:\/\/www.hostinger.com\/my\/tutorials\/django-static-files","default":0},{"locale":"en-PH","link":"https:\/\/www.hostinger.com\/ph\/tutorials\/django-static-files","default":0},{"locale":"en-IN","link":"https:\/\/www.hostinger.com\/in\/tutorials\/django-static-files","default":0},{"locale":"en-CA","link":"https:\/\/www.hostinger.com\/ca\/tutorials\/django-static-files","default":0},{"locale":"en-AU","link":"https:\/\/www.hostinger.com\/au\/tutorials\/django-static-files","default":0},{"locale":"en-NG","link":"https:\/\/www.hostinger.com\/ng\/tutorials\/django-static-files","default":0}],"_links":{"self":[{"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/posts\/120253","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/users\/185"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/comments?post=120253"}],"version-history":[{"count":9,"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/posts\/120253\/revisions"}],"predecessor-version":[{"id":134072,"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/posts\/120253\/revisions\/134072"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/media\/87036"}],"wp:attachment":[{"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/media?parent=120253"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/categories?post=120253"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hostinger.com\/tutorials\/wp-json\/wp\/v2\/tags?post=120253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}