Home > OS >  Django 4.0.5: How to properly link static files into templates
Django 4.0.5: How to properly link static files into templates

Time:06-20

I'm following the CS50W course, and I noticed a weird behavior when going through the Django lecture. In summary, I was getting a 404 error when loading the styles.css file on one of the apps.

After checking the lecture source code, the main difference was that the lecture used the following to define STATIC_URL:

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = '/static/'

And noticed that even Django's documentation defines STATIC_URL as STATIC_URL = 'static/', and somehow, adding that slash at the beginning fixes the 404 issues. Could someone explain to me why that is?

For reference, this is the project structure I have (the issue is within the app called newyear):

.
├── db.sqlite3
├── manage.py
├── myapp
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-38.pyc
│   │   ├── admin.cpython-38.pyc
│   │   ├── apps.cpython-38.pyc
│   │   ├── models.cpython-38.pyc
│   │   ├── urls.cpython-38.pyc
│   │   └── views.cpython-38.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       └── __init__.cpython-38.pyc
│   ├── models.py
│   ├── templates
│   │   └── myapp
│   │       ├── greet.html
│   │       └── index.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── newyear
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-38.pyc
│   │   ├── admin.cpython-38.pyc
│   │   ├── apps.cpython-38.pyc
│   │   ├── models.cpython-38.pyc
│   │   ├── urls.cpython-38.pyc
│   │   └── views.cpython-38.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       └── __init__.cpython-38.pyc
│   ├── models.py
│   ├── static
│   │   └── newyear
│   │       └── styles.css
│   ├── templates
│   │   └── newyear
│   │       └── index.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
└── prueba
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-38.pyc
    │   ├── settings.cpython-38.pyc
    │   ├── urls.cpython-38.pyc
    │   └── wsgi.cpython-38.pyc
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Template linking the styles:

<!DOCTYPE html>
<html lang="en">
    <head>
        {% load static %}
        <link rel="stylesheet" href="{% static 'newyear/styles.css' %}">
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Is it new year?</title>
    </head>
    <body>
        {% if newyear %}
            <h1>Yes</h1>
        {% else %}
            <h1>No</h1>
        {% endif %}
    </body>
</html>

Side note: I know this might be a basic question and I can just use what works, which is adding the slash when defining STATIC_URL, however, I would really like to understand if this is the actual proper way of doing it, and if so, why the default settings.py file comes to set up in a way that it requires the addition of the slash.

CodePudding user response:

Prior to Django 4.0 the default was, in fact, '/static/' as described by the docs.

There have been a couple of changelog entries regarding it (relatively) recently.

3.1 The STATIC_URL and MEDIA_URL settings set to relative paths are now prefixed by the server-provided value of SCRIPT_NAME (or / if not set). This change should not affect settings set to valid URLs or absolute paths.

4.0 To allow serving a Django site on a subpath without changing the value of STATIC_URL, the leading slash is removed from that setting (now 'static/') in the default startproject template.

When I've changed the setting value in 4.0 to remove or add the forward slash, it hasn't made a difference, but if the course files settings.py has been changed from the default, it may be to accommodate some other bespoke changes that are part of the course.

  • Related