Not Found: /static/css/styles.css error loading template

I’m getting an error, but only when loading a specific template.

dir structure:

Project Name -> assets -> static ->(with the following 2 subdirectories):
                                            -> css -> styles.css
                                            -> images -> favicon.png

I have a 3 basic pages, all of which extend the same layout:

home - data entry
dashboard - displays dashboard
welcome - welcome message that allows you to navigate to home or dashboard

All three apply the proper css static files, however:

  1. When I go to home, terminal displays:
[02/Nov/2024 14:32:13] "GET /ISO22301/home/ HTTP/1.1" 200 20384
Not Found: /static/css/styles.css
[02/Nov/2024 14:32:13] "GET /static/css/styles.css HTTP/1.1" 404 2553
[02/Nov/2024 14:32:13] "GET /static/static/css/styles.css HTTP/1.1" 304 0

and renders properly. None of the other files display the error message and also render properly.

Their templates terminal output is:

[02/Nov/2024 14:41:53] "GET /ISO22301/dashboard/ HTTP/1.1" 200 18874
[02/Nov/2024 14:41:53] "GET /static/static/css/styles.css HTTP/1.1" 304 0

so it appears to be something with my directory structure and /static/static/css vs /static/css. I have tried various variants in settings and the templates without fixing the issue.

  1. In addition, favicons are only loaded if I go directly via url to the dashboard page, not form the input button on home.

settings.py:

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

STATIC_URL = 'static/'
#STATICFILES_DIRS = [BASE_DIR / "static"]  # I've added and remved this to no effect
STATIC_ROOT = os.path.join(BASE_DIR, 'assets/')

Templates

layout

{% load static %}

<!DOCTYPE html>
<html lang = "en">
  {% csrf_token %}
<head>
    <link rel="stylesheet" href="{% static 'static/css/styles.css' %}">
    <title>{{ browsertab }}</title>
    <link rel="shortcut icon" type="image/png" href="{% static 'static/images/favicon.png' %}" >



    <h1>{{ dashboard_title }}</h1>


    {% block content %}
    {% endblock %}
</body>
</html>

Dashboard

{% extends "ISO22301/layout.html" %}

{% block content %}
<table>
 <body>

  <!--Create flexbox to render header graphic--> 
      <div class="container" style="top: 5%;">
  <!--Create LOO shape and iterate through rows>-->
 {% for objtext in rows %}  
 <tr><td>

  <!--Create row of topic shapes and spacer between shapes and apply status color-->
  <!--Create pointed arrow and space to Outcome-->

         {% for a_text in objtext %}

            {% if a_text.objective_position == 1 %}
              <div class="item_LoO_Name">
                {{ a_text.objective_text|linebreaks}}</div>
            {% else %}
              {% if a_text.objective_position != 10 %}
                  <div class="space"></div>
                  <a href="{% url 'testpage' %}">
                 <div class="Objective" style= 'background-color:{{ a_text.objective_background }}'>
                        {{ a_text.objective_text|linebreaks}}</div>
                 </a>
              {% else %}
                <div class="space"></div>
                <div class="triangle-right"></div>
                <div class="spaceblank"></div>
                <div class="item_Outcome_Name">
                    {{ a_text.objective_text|linebreaks}}</div>
              {% endif %} 
            {% endif %}
                  {% endfor %}

          {% endfor %}
          <div>
          {% if data_entry_button == 1 %}
            <a href="{% url 'home' %}">
            <button>Go to Data Entry</button>
            </a>
          {% endif %}
        </td>

      </div>
      </tr>  


        </div>
      </div> 

  </form>
{% endblock %}

home

{% extends "ISO22301/layout.html" %}

{% block content %}

        <form method='POST' action='{% url 'home' %}' enctype='multipart/form-data'>
          {% csrf_token %}
          <table>
<head>
          <th>Project</th>
          {% for n in objheader %}
          <th>Objective</th>
          {% endfor %}
          <th>Outcome</th>
</head>
 <body>

  {% if messages %}
  {% for message in messages %}
      {% if message.tags == 'success' %}

          <div class="alert alert-success alert-dismissible" role="alert">
              <a href="{% url 'home' %}">
              <button type="button" class="buttonmessage" data-dismiss="alert" aria-label="Close">
                {{ message|safe }}     <span aria-hidden="true">&times;</span>
                </button>
              </a>
          </div>
          {% endif %}
          {% endfor %}
      {% endif %} 


              {% for formset in formset_list %}
                {{ formset.management_form }}
                      <tr>
                                {% for form in formset %}
                                <td>  {{ form.objective_text }} {{ form.objective.as_hidden }} {{ form.id.as_hidden }}</td>
                                {% endfor %}
                      </tr>                        

              {% endfor %}
      
      </table> 
        <div>
          <input type='submit' name= 'Save' value='Save Data'>
        </div>
        <div>
          <input type='submit' name= 'Dashboard_Test' value='Go to Dashboard Test'>
          <div>
            <input type='submit' name= 'Dashboard' value='Go to Dashboard'>
          </div>
        </div>
  </form>
{% endblock %}

relevant part of views.py:

def home(request):
        #Identify current dashboard
        n=1# Dashboard id number returned from button_id in GET data
        request.session['dashboard_id'] = n  #assign dashboard_id the value n    
        dashboard_id = request.session.get('dashboard_id') # This how you retireve the id in any view       
     # Add the formset to context dictionary  
        context_items =  createcontext(dashboard_id)
        formset_list = context_items[0]
        objheader = context_items[1]
        browsertab = context_items[2]
        dashboard = context_items[3]
        context = {
            'formset_list': formset_list,
            'objheader': objheader,
            'browsertab': browsertab,
            'dashboard_title' : dashboard,
        }

        
        if request.method == "POST":#Creat a formset of teh POST data filterd by dashbaor and iterated over 6 rows
            formset_list=[ObjectivesFormSet(request.POST,prefix=f'row-{I}',
                        queryset=Objectives.objects.filter(
                        dashboard = dashboard_id, row=I
                        ).order_by('id'))
                        for i in range(1,7)
                        ]
            for formset in formset_list: # Check if formset is valid
                if formset.is_valid():
                    for form in formset:# loop through all the forms to save the data
                            form.save()
            context = {
                            'formset_list': formset_list,
                            'objheader': objheader,
                            'browsertab': browsertab,
                            'dashboard_title' : dashboard,
                        } # update context to include new data
            
            if request.POST.get('Dashboard'): #sets "'Dashboard_Test' button to 0 to not display it
                context_items =  createdashboard(dashboard_id)
                data2 = context_items[0]
                rows = context_items[1]
                data_entry_button = 0 #changes button value to 1 to display button when page called from data entry "Dashboard Test' button"
                context = {
                            'objective_text': data2,
                            'rows': rows,
                            'browsertab': browsertab,
                            'dashboard_title' : dashboard,
                            'data_entry_button': data_entry_button
                        }
                
                return render(request, 'ISO22301/dashboard.html', context)
            
            elif request.POST.get('Dashboard_Test'):
                context_items =  createdashboard(dashboard_id)
                data2 = context_items[0]
                rows = context_items[1]
                data_entry_button = 1 #changes button vlue to 1 to display button when page called from data entry "Dashboard Test' button"
                context = {
                            'objective_text': data2,
                            'rows': rows,
                            'browsertab': browsertab,
                            'dashboard_title' : dashboard,
                            'data_entry_button': data_entry_button
                        }
                
                return render(request, 'ISO22301/dashboard.html', context)
            elif request.POST.get('Save'):
                messages.success(request, "Data Saved")
                return render(request, 'ISO22301/home.html', context)
        else: # GET request
             return render(request, 'ISO22301/home.html', context)
        

def dashboard(request): #creates data for use in flexbox without data entry button
        dashboard_id = 1 #Temporary placeholder
        #dashboard_id = request.session.get('dashboard_id') # This how you retireve the id in any view     
        context_items =  createdashboard(dashboard_id)
        data2 = context_items[0]
        rows = context_items[1]
        layout_text = layouttext(dashboard_id)
        browsertab = layout_text[0]
        dashboard = layout_text[1]
        data_entry_button = 0
        context = {
                    'objective_text': data2,
                    'rows': rows,
                    'browsertab': browsertab,
                    'dashboard_title' : dashboard,
                    'data_entry_button': data_entry_button,
                }
        return render(request, 'ISO22301/dashboard.html', context)
1 Like

Sorry, this is too much stuff for me to figure out your issues, but do fix your html, because that’s not going to help anything

  • you have head and body tags inside your table. Should be thead and tbody.
  • Don’t put div tags inside your table like you have for messages. Move the messages out of the table (ideally) or put them in rows and columns.

Thanks, made those changes.

How are you running your project? Is this a development environment using runserver, or is it a production deployment using a real web server such as Apache or nginx?

What does your root urls.py file look like?

You show a STATICFILES_DIRS setting commented out. Does the log segments you posted come from a run with that setting active or commented out?

I fixed the not displaying the browser tab name, I had left off a variable in context.

Development at localhost

urlpatterns = [
    path('admin/', admin.site.urls),
    path("ISO22301/", include("ISO22301.urls")),
    path('accounts/', include('django.contrib.auth.urls')),
]

Oddly, I just did a new browser session and commenting it out or leaving it in resulted in the same log in terminal (shown below), with no errors; however the favicon still only shows up when
I use:

http://127.0.0.1:8000/ISO22301/dashboard/

to navigate to the dashboard.

It’s really strange - if I go to the dashboard from home, the browser first show “Translation Available” and the displayed url is:

http://127.0.0.1:8000/ISO22301/home

although the dashboard template is rendered properly except for the favicon.

Terminal output for going from login to welcome to home to dashboard. “Dashboard” and “Dashboard_Test” go to the same url, the only difference is “Dashboard_Test” dispalys a “Return to Entry” button that goes back to the home template.

To go to home from “Dashboard” I enter the URL. I did this to allow someone to display the dashboard but not allow them to change any entries and keep the display neater.

[03/Nov/2024 11:01:47] "GET /ISO22301/login HTTP/1.1" 301 0
[03/Nov/2024 11:01:47] "GET /ISO22301/login/ HTTP/1.1" 200 1008
[03/Nov/2024 11:01:47] "GET /static/static/css/styles.css HTTP/1.1" 304 0
[03/Nov/2024 11:01:54] "POST /ISO22301/login/ HTTP/1.1" 302 0
[03/Nov/2024 11:01:54] "GET /ISO22301/welcome/ HTTP/1.1" 200 950
[03/Nov/2024 11:01:54] "GET /static/static/css/styles.css HTTP/1.1" 304 0
[03/Nov/2024 11:01:59] "GET /ISO22301/home/ HTTP/1.1" 200 19887
[03/Nov/2024 11:01:59] "GET /static/static/css/styles.css HTTP/1.1" 304 0
[03/Nov/2024 11:02:04] "POST /ISO22301/home/ HTTP/1.1" 200 18971 #<- to dashboard url using "Dashboard" 
[03/Nov/2024 11:02:04] "GET /static/static/css/styles.css HTTP/1.1" 304 0
[03/Nov/2024 11:02:12] "GET /ISO22301/home/ HTTP/1.1" 200 19887 #<- to home url
[03/Nov/2024 11:02:12] "GET /static/static/css/styles.css HTTP/1.1" 304 0
[03/Nov/2024 11:02:15] "POST /ISO22301/home/ HTTP/1.1" 200 19084# <- to dashboard url using "Dashboard_Test" 
[03/Nov/2024 11:02:15] "GET /static/static/css/styles.css HTTP/1.1" 304 0
[03/Nov/2024 11:02:21] "GET /ISO22301/home/ HTTP/1.1" 200 19887 #<- to home url

I ran it on Heroku and all but 1 page shows the favIcon, and that page extends the same layout that displays it properly.
Templates is commented out.
When I compare the html rendered, both are rendered by extending layout, and they look the same:

working page:

<!DOCTYPE html>
<html lang = "en">
  
  <head>

    <link rel="stylesheet" href="/static/css/styles.css">
    <title>Company</title>
    <link rel='shortcut icon' type="image/png" href="/static/images/favIcon.png" >

nonworking

<!DOCTYPE html>
<html lang = "en">
  
  <head>

    <link rel="stylesheet" href="/static/css/styles.css">
    <title>Company</title>
    <link rel='shortcut icon' type="image/png" href="/static/images/favIcon.png" >

  <ul>

Layout.html:

<!DOCTYPE html>
<html lang = "en">
  {% load static %}
  <head>

    <link rel="stylesheet" href="{% static 'css/styles.css' %}">
    <title>{{ browsertab }}</title>
    <link rel='shortcut icon' type="image/png" href="{% static 'images/favIcon.png' %}" >

  <ul>

  <form class="logout" action="{% url 'logout' %}" method="POST">
  {% csrf_token %}
 <li> 
  <button class='buttonheader' type="submit">Log Out</button>
 </li>
</form>
      
  </ul>

    <h1>{{ dashboard_title }}</h1>

  </head>
    {% block content %}
    {% endblock %}

</html>

settings

LOGOUT_REDIRECT_URL = "bye"
LOGIN_REDIRECT_URL = "welcome"
STATICFILES_DIRS = [
    BASE_DIR / "assets/static",
]

It looks like you’re still serving invalid html here.

Your template is showing that you have a form being rendered inside the <head> of the html instead of the <body>, and you’re not showing a <body>.

Ok. I think I fixed the layout.html template by adding tags, moved the logout button to body, added meta tag, and removed meta and body from templates that extend layout:


<!DOCTYPE html>
<html lang = "en">
  {% load static %}
  <head>

    <link rel="stylesheet" href="{% static 'css/styles.css' %}">
    <title>{{ browsertab }}</title>
    <link rel='shortcut icon' type="image/png" href="{% static 'images/favIcon.png' %}" >
  </head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <body>
  <ul>

  <form class="logout" action="{% url 'logout' %}" method="POST">
  {% csrf_token %}
 <li> 
  <button class='buttonheader' type="submit">Log Out</button>
 </li>
</form>
      
  </ul>

    <h1>{{ dashboard_title }}</h1>

 
    {% block content %}
    {% endblock %}
</body>
</html>

Welcome:

{% extends "ISO22301/layout.html" %}

{% block content %}



    <h1>Click button to select data entry or view dashboard</h1>
    <div class="container">
        <div>
            <a href="{% url 'dashboard' %}">
            <button>View Dashboard</button>
            </a>
        <div>
            <a href="{% url 'dataentry' %}">
            <button>Go to Data Entry</button>
            </a>
        </div>
    </div>
{% endblock %}

HTML rendered by welcome on Heroku:


<!DOCTYPE html>
<html lang = "en">
  
  <head>

    <link rel="stylesheet" href="/static/css/styles.css">
    <title>Company</title>
    <link rel='shortcut icon' type="image/png" href="/static/images/favIcon.png" >
  </head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <body>
  <ul>

  <form class="logout" action="/ISO22301/logout/" method="POST">
  <input type="hidden" name="csrfmiddlewaretoken" value="24AiDxe3QzNp0RneOd1JbfwVAVjmZQLkIp7YcDKYbQrIqcfk88rkk1JEHvG3gzIA">
 <li> 
  <button class='buttonheader' type="submit">Log Out</button>
 </li>
</form>
      
  </ul>

    <h1>Company</h1>

 
    



    <h1>Click button to select data entry or view dashboard</h1>
    <div class="container">
        <div>
            <a href="/ISO22301/dashboard/">
            <button>View Dashboard</button>
            </a>
        <div>
            <a href="/ISO22301/dataentry/">
            <button>Go to Data Entry</button>
            </a>
        </div>
    </div>

</body>
</html>

Header for dashboard that shows favIcon:

<!DOCTYPE html>
<html lang = "en">
  
  <head>

    <link rel="stylesheet" href="/static/css/styles.css">
    <title>Company</title>
    <link rel='shortcut icon' type="image/png" href="/static/images/favIcon.png" >
  </head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <body>

...

This is the same project as with this Post.

I would advise @jlc1978 to setup a fresh project using the skeleton (snippet) I proffered there then build on it. @jlc1978 please study that skeleton. It will help you. I also cleaned up on your HTML there. If you have any questions about that solution, ask. Most of the issues apply to this thread too.

Thanks. I will try that.
I fixed the favIcon not being displayed issue by duplicating a working template and replacing the body from the template that didn’t display the icon and now everything works properly.