4

Background: I'm using the Django manage.py runserver for local development. I have the contrib.staticfiles in installed apps and I'm using its {% static %} template tag in my templates.

What I try to achieve: For development, I'd like to use an independent server for serving the static files but use the django development server to serve the Django app. So that I could access the page locally on my computer at http://127.0.0.1:8000, but all the static files would be served from another computer or from a different server on the localhost, as defined by the settings.STATIC_URL variable.

The problem: The settings.STATIC_URL variable is somehow overridden when I'm using the development server. So all my static files are served by the local django development server instead of what I defined in settings.STATIC_URL.

Solution: See Daniel's answer below!

settings.py:

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_URL = os.path.join('127.0.0.1:666', BASE_DIR, 'static/')

example_template.html:

{% load staticfiles %}
{% load bootstrap3 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery=True%}
{% bootstrap_messages %}

{# Load MyApp CSS #}
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700subset=greek-ext,vietnamese,cyrillic-ext,latin-ext' rel='stylesheet' type='text/css'>
<link href="{% static 'css/my_app.main.css' %}" rel="stylesheet">

page source when using a browser:

<link href="FULL_PATH_TO_BASE_DIR_HERE/static/css/my_app.main.css" rel="stylesheet">

but expected to see:

<link href="127.0.0.1:666/FULL_PATH_TO_BASE_DIR_HERE/static/css/my_app.main.css" rel="stylesheet">
zenperttu
  • 764
  • 1
  • 7
  • 13
  • No, the URL is not overridden unless you do it yourself. Please show the relevant parts of your settings file, and the views/templates where you are using that value. – Daniel Roseman Jun 09 '16 at 18:34
  • I hope this contains the necessary lines! I'm only accessing the static files from my templates using the {% static %} tag (I'm not accessing them from my views). – zenperttu Jun 09 '16 at 20:16
  • Have you tried to remove `django.contrib.staticfiles` from your `INSTALLED_APPS`? – Håken Lid Jun 09 '16 at 20:40

1 Answers1

3

This isn't anything to do with Django or runserver. It's simply because you are using os.path.join() to join a domain and a path; that function doesn't know about URLs, and will assume that since BASE_DIR starts with a leading slash, it should normalize the whole path to start from there and ignore anything previous:

>>> os.path.join('127.0.0.1', '/foo', 'static')
'/foo/static'

The solution is twofold: don't use os.path.join on URLs, but more importantly, don't use BASE_DIR in your STATIC_URL. The filesystem directory your static files live in has nothing whatsoever to do with the URL they are exposed on. Your STATIC_URL should be something like "http://127.0.0.1:666/static/".

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Whoah, glad I asked this question here! Would have taken me ages to figure this out! I was for some reason thinking I os.path.join was doing what os.sep.join does. It is also very helpful you pointed out how the URL mapping to the filesystem is not a 1:1 thing. Here, I was serving my entire filesystem starting from root on the localhost so that I could use a full absolute path to my folder, thinking it would help me solve this issue. Will definitely not do this in production! :) Thank you! – zenperttu Jun 10 '16 at 05:29