Blog webpage can't find static file

I’m creating a gaming blog and I’m trying to add a background image for the homepage, but Django is having an issue accessing my static files.

Rather than loading the image, it displays an icon of a sheet of paper along with my placeholder text. I also cannot access the file directly in Visual Studio via the URL as it gives me a 404 error.

Here is my settings.py:

from pathlib import Path
import os

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = 'django-insecure-t_6omw0vumbdr0c(pt%%-%2x!%b-r8#-=yc7!(luzn6f)nw-mn'

DEBUG = True

ALLOWED_HOSTS = []


INSTALLED_APPS = [
    "blog.apps.BlogConfig",
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'personal_blog.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR / "templates/",
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'personal_blog.wsgi.application'



DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]



LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


STATIC_URL = '/static/'
STATIC_ROOT = 'C:\\Python312\\TheGamesLounge\\static'


DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Here is my base.html:

<!DOCTYPE html>

{% load static %}

<html lang="en">

<head>

<meta charset="utf-8">

<title>The Gaming Lounge</title>

<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">

</head>

<body>

<h1>The Gaming Lounge</h1>

<img src="{% static 'images/game_controller.jpg' %}" alt="A picture of a game controller">

<a href="{% url "blog_index" %}">Home</a>

<a href="{% static 'test.txt' %}">Test File</a>

<hr>

{% block page_title %}{% endblock page_title %}

{% block page_content %}{% endblock page_content %}

</body>

</html>

The image file I’m trying to access is “game_controller.jpg” in static/images (I originally had it in /static with no images subfolder, but thought creating the subfolder would remedy the issue. No dice. I also created a test.txt which doesn’t load either.)

I have also double-checked permissions of the static directory and also tried the collectstatic command.

Please clarify if this is your development or your deployment environment.

If it’s your deployment environment, please describe it. (What web server and wsgi container you’re using, what operating system it’s running one, how you’re running it, etc.)

If it’s your development environment, post your DEBUG setting.

Also post all the STATIC-related settings from your settings file.

Development environment, using VS Code.

DEBUG is set to True

From settings.py:

STATIC_URL = '/static/'
STATIC_ROOT = 'C:\\Python312\\TheGamesLounge\\static'

Have you followed all the steps as listed at How to manage static files (e.g. images, JavaScript, CSS) | Django documentation | Django for configuring static files and serving static files in development?

If so, then also post your STATICFILES_DIRS setting and the contents of your root urls.py file for verification.

Yes I have followed all those steps.

I haven’t got a STATICFILES_DIRS setting because I’m only using the static/ directory inside the app.

Here is blog\urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path("", views.blog_index, name="blog_index"),
    path("post/<int:pk>/", views.blog_detail, name="blog_detail"),
    path("category/<category>/", views.blog_category, name="blog_category"),
]

Here is personal_blog\urls.py:


from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("blog.urls")),
]

Please confirm that the image file you’re trying to load is in the directory:
BASE_DIR/personal_blog/static/images/game_controller.jpg
and that that text file is in:
BASE_DIR/personal_blog/static/test.txt

When you say BASE_DIR, is this referring to my custom project name? Or does it literally need to be “BASE_DIR”?

If the former, then yes. It was originally in BASE_DIR/static/images/game_controller.jpg and BASE_DIR/static/images/test.txt, but I’ve now moved the static directory into personal_blog. Still having the same issue.

Your assumption is correct, I was referring to your project directory.

Please show the specifics of your directory layout. Starting from the project directory, post the output of an ls -R command if you’re working in Linux (or any Unix-style environment) or dir /s /w for Windows.

dir : Cannot find path 'C:\s\w' because it does not exist.
At line:1 char:1
+ dir /s/w
+ ~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\s\w:String) [Get-ChildItem], ItemNotF  
   oundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCo  
   mmand

There’s a space between the “/s” and the “/w”: dir /s /w, and you need to do this from the command line, not the powershell. (I don’t know what the equivalent powershell command would be.)

The forum isn’t allowing me to post the entirety of the output due to having too many characters. Is there a specific section you’re looking for that I can post?

You’re doing this from within your project dir? (Do you have your virtual environment inside your project?)

Anyway, just go ahead and do it in your app’s directory (personal_blog).

Yes and the venv directory is inside the BASE_DIR.

For personal_blog:

C:\Python312\TheGamesLounge\personal_blog>dir /s /w
 Volume in drive C is OS
 Volume Serial Number is 0645-5AFE

 Directory of C:\Python312\TheGamesLounge\personal_blog

[.]           [..]          asgi.py       settings.py   [static]      urls.py       wsgi.py       __init__.py
[__pycache__]
               5 File(s)          5,186 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static

[.]        [..]       [admin]    [images]   test.txt
               1 File(s)              0 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin

[.]   [..]  [css] [img] [js]
               0 File(s)              0 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\css

[.]                           [..]                          autocomplete.css              base.css
changelists.css               dark_mode.css                 dashboard.css                 forms.css
login.css                     nav_sidebar.css               responsive.css                responsive_rtl.css
rtl.css                       unusable_password_field.css   [vendor]                      widgets.css
              13 File(s)         91,310 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\css\vendor

[.]       [..]      [select2]
               0 File(s)              0 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\css\vendor\select2

[.]                  [..]                 LICENSE-SELECT2.md   select2.css          select2.min.css
               3 File(s)         33,448 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\img

[.]                      [..]                     calendar-icons.svg       [gis]
icon-addlink.svg         icon-alert.svg           icon-calendar.svg        icon-changelink.svg
icon-clock.svg           icon-deletelink.svg      icon-hidelink.svg        icon-no.svg
icon-unknown-alt.svg     icon-unknown.svg         icon-viewlink.svg        icon-yes.svg
inline-delete.svg        LICENSE                  README.txt               search.svg
selector-icons.svg       sorting-icons.svg        tooltag-add.svg          tooltag-arrowright.svg
              21 File(s)         16,915 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\img\gis

[.]                   [..]                  move_vertex_off.svg   move_vertex_on.svg
               2 File(s)          2,258 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\js

[.]                          [..]                         actions.js                   [admin]
autocomplete.js              calendar.js                  cancel.js                    change_form.js
core.js                      filters.js                   inlines.js                   jquery.init.js
nav_sidebar.js               popup_response.js            prepopulate.js               prepopulate_init.js
SelectBox.js                 SelectFilter2.js             theme.js                     unusable_password_field.js
urlify.js                    [vendor]
              18 File(s)         79,590 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\js\admin

[.]                       [..]                      DateTimeShortcuts.js      RelatedObjectLookups.js
               2 File(s)         28,416 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\js\vendor

[.]       [..]      [jquery]  [select2] [xregexp]
               0 File(s)              0 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\js\vendor\jquery

[.]             [..]            jquery.js       jquery.min.js   LICENSE.txt
               3 File(s)        373,944 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\js\vendor\select2

[.]                   [..]                  [i18n]                LICENSE.md            select2.full.js
select2.full.min.js
               3 File(s)        253,902 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\js\vendor\select2\i18n

[.]          [..]         af.js        ar.js        az.js        bg.js        bn.js        bs.js        ca.js
cs.js        da.js        de.js        dsb.js       el.js        en.js        es.js        et.js        eu.js
fa.js        fi.js        fr.js        gl.js        he.js        hi.js        hr.js        hsb.js       hu.js
hy.js        id.js        is.js        it.js        ja.js        ka.js        km.js        ko.js        lt.js
lv.js        mk.js        ms.js        nb.js        ne.js        nl.js        pl.js        ps.js        pt-BR.js
pt.js        ro.js        ru.js        sk.js        sl.js        sq.js        sr-Cyrl.js   sr.js        sv.js
th.js        tk.js        tr.js        uk.js        vi.js        zh-CN.js     zh-TW.js
              59 File(s)         55,917 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\admin\js\vendor\xregexp

[.]              [..]             LICENSE.txt      xregexp.js       xregexp.min.js
               3 File(s)        489,461 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\static\images

[.]                   [..]                  game_controller.jpg
               1 File(s)         46,824 bytes

 Directory of C:\Python312\TheGamesLounge\personal_blog\__pycache__

[.]                        [..]                       settings.cpython-312.pyc   urls.cpython-312.pyc
wsgi.cpython-312.pyc       __init__.cpython-312.pyc
               4 File(s)          4,570 bytes

     Total Files Listed:
             138 File(s)      1,481,741 bytes
              50 Dir(s)  145,814,188,032 bytes free

C:\Python312\TheGamesLounge\personal_blog>

What is the command line being used to run your project?

C:\Python312\TheGamesLounge> python manage.py runserver

I’m confused by your listing. I thought personal_blog was the app directory?

I can see now that blog is the app directory. That’s where the static directory needs to reside for that images directory and text file - not in personal_blog.

I’m following a tutorial from a 3rd party website about creating a blog, and it asked me to create a personal_blog directory. That is likely the source of confusion.

I moved the static directory to /blog, but the image still isn’t loading. Only the placeholder text loads with an icon of a piece of paper.

Generally speaking, you will have both.

See Is the structure of the project correct? - #2 by KenWhitesell as a model of what your directory structure should look like. (Note that the model showing an app1 directory inside of the app’s static directory is not required. It is only helpful when you are creating a system using multiple apps. See the Template namespacing note box.)

Please show the output of a dir /s /w of your blog directory, along with the contents of your apps.py file that is in that directory.

Whenever I run dir /s /w on my blog directory, the output is too many characters to allow me to post here. In fact, it takes up the entire terminal window - to the point where I’m not sure even scrolling to the top of the terminal lets me view the beginning of the output, because it’s so long. It seems partially cut off.

blogs/apps.py:

from django.apps import AppConfig


class BlogConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'blog'

What do you have in your blog directory containing that many files? That alone sounds like an issue.

At most, there would generally be about 10 files and 5 directories.