Yoseph Alabdulwahab
Yoseph Alabdulwahab

Reputation: 13

How does django static exactly work

I have always used PHP and finally decided to get out of that cave and explore other scripting languages like django.

I am still wrapping my head around project structure in django and can't seem to figure out how to include css, js, and other so called static files.

I have read up on the django wiki and I know I am supposed to use static to reference these files. But in order to do so I need to define my static directory in settings.py.

I have noticed that when I call static {% 'filename.extension' %} it appends the file to the static directory defined in settings.py. But if I am understanding this right that is all it does. The issue is then I have some html code that is trying to get a file from localhost:8000/static/directory/filename.extension But since python handles urls differently the html code will not get any file from such url and thus my css won't be loaded.

My settings.py

My file structure:

PassWard >
    PassWard >
        __pycache__ >
        wardvault >
            __pucache__ >
                ... (pycache stuff) ...
            templates >
                imports.html
                menu.html
                wardvault >
                    base.html
                    passwords.html
            migrations >
                ... (migration stuff) ...
            __init__.py
            admin.py
            admin.pyc
            apps.py
            models.py
            models.pyc
            tests.py
            views.py
            views.pyc
        __init__.py

    static >
        font_awesome >
            ... (lots of font related files) ...
        js >
            jquery.min.js
        imports.html
        menu.css
        menu.html
        menu.js
        reset.css
    db.splite3
    manage.py

My settings.py looks like:

"""
Django settings for PassWard project.

Generated by 'django-admin startproject' using Django 1.9.8.

For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 't+*07vdh&h^c*2ito-9_ywo^mcxps1o$e@^gb$%6vy7m5vr_^3'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'PassWard.wardvault',
]

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

ROOT_URLCONF = 'PassWard.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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 = 'PassWard.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

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',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


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

STATIC_URL = '/static/'

I am trying to load the static files into passwords.html inside wardvault.

My html snippit that is trying to access static files looks like this:

<link rel="stylesheet" type="text/css" href="{% static '/static/menu.css' %}"/>

And the result of {% static '/static/menu.css' %} when I just put it alone is /static/menu.css.

My question is when I use static does it just append what is defined in settings.py to the arguments? If so when the STATIC_URL is set to /static/ does that first slash mean starting from the project root dir or the system root dir? Also i'm I using it correctly? or is there something I am missing?

Feel free to point out bad practices with the structure of the project. I am still trying to wrap my head around everything.

Upvotes: 1

Views: 192

Answers (1)

Rohit Jain
Rohit Jain

Reputation: 213371

When you use the static tag in your template:

<link rel="stylesheet" type="text/css" href="{% static '/static/menu.css' %}"/>

It will just be expanded by replacing the {% static part, with the STATIC_URL value. So that tag becomes:

<link rel="stylesheet" type="text/css" href="/static/static/menu.css" />

You see, there are 2 /static/ now there. And given that it starts with a slash, it will be looked on at the root of your application. Now, given your directory structure, your tag should really be just: {% static 'menu.css' %}

Now coming to how to serve the file? There are 2 options:

  1. When you're running development server, you can let the django's static app serve the file. Django - serving static files during development

  2. In production server, you can let nginx, or apache, serve the static files. Check Django staticfiles "deployment" section

Another important settings related to static apps is STATIC_ROOT. It's the path which is intended to store all your static assets. And that is where python manage.py collectstatic command will collect the static files. So, ideally the STATIC_URL location in your nginx or apache should be aliased to that directory.

Upvotes: 1

Related Questions