3

I'm afraid I'm at a loss here, I checked out some similar questions but none of them seem to apply.

I am running the django developement server on my laptop. I use it to serve static files as well. I have a folder in the static root which contains the CSS for 2 templates both called base.html.

this is the head section of the one that works:

<head>
    <title>| Entries | Latest entries</title>
    <link rel="stylesheet" type="text/css" href="/static/css/serenity.css" />
</head>

here is the one which does not:

<head>
    <title>Latest Photo Galleries</title>
    <link rel="stylesheet" type="text/css" href="/static/css/photologue.css" />
</head>

urls.py:

    (r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.STATIC_ROOT}),

and the static URL:

    STATIC_URL = '/static/'

The STATIC_ROOT is an absolute path.

when I look at the source and try to open the link to the css I get a 404(not found)

why does Django serve the css file for one app but not the other? (the one not working is in the photologue template.)

Any help would be appreciated.

Maarten
  • 492
  • 7
  • 14
  • I know it's a stupid question, but is the file actually *in* that directory? Try loading it directly in your browser. If you get a 404, well, ... – Peter Rowell Jan 26 '12 at 22:36
  • Since he runs them in Django dev server, he should be able to see requests in the server windows itself along with their respective response codes. – MK_Dev Jan 26 '12 at 22:40
  • I get the following output from the server window: "GET /Static/css/photologue/css HTTP/1.1" 404 1745 The file loads directly into the browser. – Maarten Jan 26 '12 at 22:45
  • 1
    If you copy-pasted that error correctly there are not 1 but *2* errors in it. `/Static` should be `/static` and `photologue/css` should be `photologue.css` – Peter Rowell Jan 27 '12 at 01:04
  • I had to type the error I saw in the prompt, so I made a typo and capitalized the first 'S' :) very perceptive though. – Maarten Jan 27 '12 at 09:28

4 Answers4

12

The way you are using staticfiles is slightly incorrect. While I can't tell you exactly what is causing your current situation, I can tell you that your method will cause you headaches in the future. First things first though, I agree with the comments about watching your request traffic in the Django server terminal. Look for 4xx responses and make sure the requested URL is correct. This: /Static/css/photologue/css has two errors in it.

If you don't want to read further, drop the urls.py static.server line and watch the server terminal. Now, here's how it's all working...

You've got your settings variables correct but you may misunderstand the purpose of STATIC_ROOT. STATIC_URL is the fully qualified or relative URL for your static files. STATIC_ROOT is the folder that will ultimately hold all the static files. It should be empty. Django is responsible for filling it via the manage.py collectstatic command. The idea is each app in your Django project has its own static/ folder with the js/css/image assets that it needs. In addition, Django will collect the static assets for the Admin and any other third-party packages you use. All of these assets will be organized into your STATIC_ROOT folder. It's not safe to assume files you have their prior to collection will remain.

STATIC_ROOT = '/path/to/empty/static/folder/'  # or something dynamic with os.path methods
STATIC_URL = '/static/'

In your case maybe your serenity app has serenity/static/css/serenity.css and photologue has photologue/static/css/photologue.css. You could put shared assets in a base/static/ folder.

Now for properly serving static media. Do not use the 'django.views.static.serve' line in urls.py. Django's runserver will automatically serve static files. Behind the scenes it is handling the collectstatic behavior and gathering all your static assets together and serving them up. Using that type of URL pattern in Django 1.3 is unnecessary, a source of confusion, and the kind of thing that will mistakenly go to production. Remember, your webserver (Apache/Nginx) serves static assets. Your Django urls.py files don't need to know a thing about 'em.

Referring to the static URL in templates. You've got /static/ hardcoded in your templates. That will work (but only because STATIC_URL is the same value). To be more flexible about it, you've got three options.

  1. Use href="{{ STATIC_URL }}css/photologue.css". That variable will be in your templates as long as you include 'django.core.context_processors.static' in your TEMPLATE_CONTEXT_PROCESSORS.
  2. Use a templatetag: {% load static %} ... href="{% get_static_prefix %}css/photologue.css"
  3. In Django 1.4 you'll be able to use {% load static from staticfiles %}... href="{% static 'css/photologue.css' %}"

It's worth reading up on static files in Django and being aware of the changes coming in Django 1.4

JCotton
  • 11,650
  • 5
  • 53
  • 59
  • Thanks for the very clear explanation! I emptied the folder indicated as STATIC_ROOT and ammended urls.py. I used option 2 from your answer above. My app folders indeed already had a static subfolder( app/static/css etc.) in them. the css files are being served properly now. django-markitup is now now working in admin but I'll see if I can resolve that myself befor asking another question. thanks again. – Maarten Jan 27 '12 at 09:25
  • Thank you for the explanation, just starting out with Django and this fixed my issue! – adefran83 Oct 12 '14 at 01:38
1

I see two issues that are likely to happen:

  • The STATIC variables were not set in your settings file.

(you had lots of answers for this)

  • You have probably not set the /static/ alias in your apache config.

Add this line to your /etc/apache2/httpd.conf file or /etc/apache2/sites-available/myDjangoConfig:

Alias /static/ {valueOfSTATIC_ROOT}

Then restart your Apache server:

sudo service apache2 reload
j0k
  • 22,600
  • 28
  • 79
  • 90
Lilley
  • 214
  • 1
  • 5
0

STATIC_ROOT is not used with Django dev server - only when you deploy to prod or use a different server. STATIC_ROOT is where your static files WILL be stored once you collect them (using "collectstatic" method).

The reason it works for one app but not the other, is because one app has the right reference to the CSS folder, whereas the other one doesn't. For starters, try copying "static" dir from one app to the other and see if it work.

Much more info here: https://docs.djangoproject.com/en/1.3/howto/static-files/

MK_Dev
  • 3,291
  • 5
  • 27
  • 45
0

You can try these steps:

  1. open your settings.py and

-add this at the first line of your file:

import os.path
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))

-change your STATIC_ROOT's value to:

STATIC_ROOT = os.path.join(PROJECT_DIR, 'static/')

-change your STATIC_URL's value to:

STATIC_URL = '/static/'
  1. create a folder named "static" in your project root.
  2. create a folder for your static files like css, javascript and etc. I recommend you use a different folder for different types of files.
  3. open the urls.py of your project -add this to your imports: import settings -add this to the url patterns:

    (r'(?:.*?/)?(?P(css|jquery|jscripts|images)/.+)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT }),

    NOTE: In this example, there are folders named css, jquery, jscripts and images inside my static folder.

  4. In your template add this:

for css files: (in this example, default.css is the name of the css file)

<link href="{{ STATIC_URL }}css/default.css" rel="stylesheet" type="text/css" media="all" />

for javascript:

<script type="text/javascript" src="{{ STATIC_URL }}jquery/jquery.js"></script>
casperOne
  • 73,706
  • 19
  • 184
  • 253
Amazing Angelo
  • 1,658
  • 2
  • 13
  • 8
  • Using STATIC_ROOT in the template is wrong; it should be STATIC_URL and preceding it with a "/" is incorrect as well. Also, populating a "static" folder in the project root will not work with the `collectstatic` paradigm. That folder is a collection point. When you run `manage.py collectstatic` you'll see a message like this, "You have requested to collect static files at the destination location as specified in your settings file. This will overwrite existing files. Are you sure you want to do this?" – JCotton Jan 27 '12 at 02:43