{"id":120253,"date":"2024-12-18T00:46:04","date_gmt":"2024-12-18T00:46:04","guid":{"rendered":"\/tutorials\/?p=120253"},"modified":"2026-03-09T19:17:00","modified_gmt":"2026-03-09T19:17:00","slug":"django-static-files","status":"publish","type":"post","link":"\/ng\/tutorials\/django-static-files","title":{"rendered":"Django static files: How to configure and serve them"},"content":{"rendered":"<?xml encoding=\"utf-8\" ?><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<\/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=\"\/ng\/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\">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><?xml encoding=\"utf-8\" ?><figure class=\"wp-block-image size-large\"><a class=\"hgr-tutorials-cta hgr-tutorials-cta-vps-hosting\" href=\"\/ng\/vps-hosting\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" 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=\"auto, (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=\"\/ng\/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. You need to manage static files carefully because Django treats them differently in development and production environments. Configuring and serving Django static files involves four key stages: How to configure static files in Django settings [&#8230;]<\/p>\n<p><a class=\"btn btn-secondary understrap-read-more-link\" href=\"\/ng\/tutorials\/django-static-files\">Read More&#8230;<\/a><\/p>\n","protected":false},"author":185,"featured_media":143557,"comment_status":"open","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":[22644],"tags":[],"class_list":["post-120253","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vps"],"hreflangs":[{"locale":"en-US","link":"https:\/\/www.hostinger.com\/tutorials\/django-static-files","default":0},{"locale":"en-UK","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\/ng\/tutorials\/wp-json\/wp\/v2\/posts\/120253","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/users\/185"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/comments?post=120253"}],"version-history":[{"count":10,"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/posts\/120253\/revisions"}],"predecessor-version":[{"id":143556,"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/posts\/120253\/revisions\/143556"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/media\/143557"}],"wp:attachment":[{"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/media?parent=120253"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/categories?post=120253"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hostinger.com\/ng\/tutorials\/wp-json\/wp\/v2\/tags?post=120253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}