Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django static files, and filepaths in settings.py

Tags:

python

css

django

I'm trying my first proper webdev project and i'm learning the django framework.

I came here to ask about the cleanest way to use "static files", like the external CSS i'm referring to in one of my html templates. I tried reading through the official documentation on the subject but found it a little bit confusing as a beginner, i then tried googling but i noticed that most of the guides or stackoverflow answers differed slightly and i realised i needed a better understanding. Bit cheeky to ask but, could someone explain and summarise the process to me?

For reference, here is my project folder hierarchy. At the moment i'm trying to get the template base.html to use the sylesheet at CSS/base.css: enter image description here

Also one of the things that keeps throwing me off is the use of absolute filepaths. So far i've managed to get away with just using relative filepaths, which makes more sense to me as the aim is to develop on the django test server then transfer it all onto my own server when i have one. (note: perhaps it's because i have no idea how complicated that transfer process is that i don't understand why absolute filepaths are prefered). What's the issue with using relative filepaths?

I realise that this has sort of become two questions, which is against the rules, but i really think both could be answered together and if i understood one it would probably aid my understanding of the other. Any help would be much appreciated.

like image 761
Holly Avatar asked Jun 10 '12 15:06

Holly


People also ask

What is static files and media files in Django?

First off, you'll typically find these three types of files in a Django project: Source code: These are your core Python modules and HTML files that make up every Django project, where you define your models, views, and templates. Static files: These are your CSS stylesheets, JavaScript files, fonts, and images.

What is static files in Django?

Static Files such as Images, CSS or JS files are often loaded via a different app in production websites to avoid loading multiple stuff from the same server.

How do you serve static files in Django in production?

Serving static files in production. The basic outline of putting static files into production consists of two steps: run the collectstatic command when static files change, then arrange for the collected static files directory ( STATIC_ROOT ) to be moved to the static file server and served.


3 Answers

Here is a set of code snippets from settings.py i have changed for including static files

import os
import django
DJANGO_ROOT = os.path.dirname(os.path.realpath(django.__file__))
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

Dynamically setting variables for SITE_ROOT directory

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

where the sqlite3 database is stored it needs absolute address

            'USER': '',
            'PASSWORD': '',
            'HOST': '',                     
            'PORT': '',                     
        }
    }


STATIC_ROOT = SITE_ROOT
STATIC_URL = '/static/'

store static files here

STATICFILES_DIRS = (
    os.path.join(SITE_ROOT,'static'),
       )

where the templates are stored

TEMPLATE_DIRS = (
    os.path.join(SITE_ROOT,'templates'),

)

Now in templates use

 {% load static %} --at beginning
<link href="{% static "css/bootstrap.min.css"%}" rel="stylesheet" media="screen">

this is an example showing how to access "css/bootstrap.min.css" in static directory

like image 97
Sarath Sadasivan Pillai Avatar answered Oct 18 '22 22:10

Sarath Sadasivan Pillai


I'm going to assume you're using Django 1.3 or higher as that allows you to use staticfiles (docs) for static files. Here's the basic idea: each Django website consists of multiple apps (directories) that contain all the files needed for a particular part of the website (i.e., a models.py, views.py, a templates directory and also a static directory). This static directory contains the JavaScript and CSS files (as well as other static files for that app.

When deploying the website, you run the collectstatic command to gather all the static files into one directory. From that directory you then serve the static files to visitors of your site (i.e, Apache or a different web server can do that for you).

So the general structure of your web project could be:

  • manage.py
  • website/models.py
  • website/views.py
  • website/static/website/css/base.css
  • website/static/website/js/base.js
  • website/templates/website/base.html
  • static
  • settings.py
  • urls.py

You'll notice that the name of the Django app is repeated in the subdirectories of the static and templates directories. This is necessary because it keeps the files apart when they are moved to a general static directory. In the above example, the STATIC_ROOT is the top-level static directory and into this directory all your static files will be copied.

It's definitely worth reading the documentation of staticfiles as this project layout allows you to reuse Django apps in other projects with ease. For example, you can imagine a website that looks like this:

  • blog/models.py
  • blog/templates/blog/overview.html
  • blog/templates/blog/post.html
  • blog/urls.py
  • blog/views.py
  • photos/models.py
  • photos/templates/photos/overview.html
  • photos/templates/photos/photo.html
  • photos/urls.py
  • photos/views.py
  • manage.py
  • static
  • settings.py
  • urls.py

The apps blog and photos can now easily be reused in other websites if desired.

like image 32
Simeon Visser Avatar answered Oct 19 '22 00:10

Simeon Visser


Really appreciate the time put into the @Simeon Visser's answer, and there was some really useful information there but it wasn't entirely what I was looking for. So I asked around and have sinister_user_name from reddit to thank for this, which I thought might help someone else:


Static files have changed a fair bit in recent releases so old blogs might be a bit of a mess.

I'll give it a shot:

In your templates you can use the static_url tag and django will fill in the path for you.

<link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap.min.css">

It fills in the static url by looking at your settings file. STATIC_URL defaults to /static/ I think in settings? If static files end up in a weird url on your corporate web server you can just change it in settings anyway and it will reflect in all templates. So it doesn't matter if they are absolute.

When you go to deploy you fill in STATIC_ROOT in your settings, this is just the path that you've set your webserver to find the static files. Then if you run manage.py collectstatic and it will copy them to that directory. That's the only function of STATIC_ROOT I think.

I keep the template directory separate from my static directory, mainly because you want your webserver just to serve static files, while templates are processed by python. So, static files are almost not part of your application as far as the web server views them. I keep my templates and static files in separate paths just in the base directory, mainly because both are not python source files.

So my project structure would be like:

manage.py
website/settings.py
app/models.py
app/views.py
templates/base.html
static/js/jquery.js
static/css/bootstrap.css

The problem with relative paths is that they will need to change if your url scheme changes.

Optional: I found in this blog which helps to not put absolute file system paths into the settings.py which is good if your working from multiple machines eg work and home :( With the slightly different layout for 1.4 I use this at the top of my settings:

import os
import django
import manage

DJANGO_ROOT = os.path.dirname(os.path.realpath(django.__file__))
SITE_ROOT = os.path.dirname(os.path.realpath(manage.__file__))

instead of what they suggest (the location of settings has moved in 1.4 or 1.3) so SITE_ROOT is messed up. I think that might work. Further on down in the settings I use this:

# Additional locations of static files
STATICFILES_DIRS = (
    os.path.join(SITE_ROOT, 'static'),
)

This will tell the development server where to find the static files. You can do the same for templates or just use the full file path.

like image 1
Holly Avatar answered Oct 18 '22 22:10

Holly