Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serve admin static files with django.contrib.staticfiles in Django 1.4 (using one Apache server)?

Django is recommending me that if I am going to only use one server (Apache) to serve both dynamic and static files, then I should serve static files using django.contrib.staticfiles.

So in my settings.py I have loaded django.contrib.staticfiles to my INSTALLED_APPS and django.core.context_processors.static to my TEMPLATE_CONTEXT_PROCESSORS.

I noticed in the admin templates that it links to static files like this (from index.html):

{% load i18n admin_static %}

{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}

But looking at the template tag admin_static, it's simply a wrapper for static:

from django.conf import settings
from django.template import Library

register = Library()

if 'django.contrib.staticfiles' in settings.INSTALLED_APPS:
    from django.contrib.staticfiles.templatetags.staticfiles import static
else:
    from django.templatetags.static import static

static = register.simple_tag(static)

So I concluded that because every admin static file is serverd with a admin/... prefix, then the full path (for my case) should be

/usr/lib64/python2.7/site-packages/django/contrib/admin/static

So I set that path to my STATICFILES_DIRS inside settings.py, but Apache still won't serve any static files (after restating the server). Where did I make a mistake in my logic?

like image 338
hobbes3 Avatar asked Mar 31 '12 21:03

hobbes3


2 Answers

The documentation you link to doesn't say anything at all about serving files with the staticfiles app. That's not what it's for: it's for collecting staticfiles into a single place to allow them to be easily served by Apache. (It does deal with serving files in development, but that's not what we're talking about here.)

You still need to set up Apache to serve the files from the relevant location via the static/ prefix.

like image 27
Daniel Roseman Avatar answered Sep 19 '22 10:09

Daniel Roseman


Thanks Daniel Roseman for the explanation and giving me the chance to learn it on my own (and now I won't forget!) :-).

Initially I was really confused and I didn't know you had to first collect the static files, then tell Apache to serve it. I thought simply using STATICFILES_DIRS and including the static app in settings.py was good enough.

So here is how I did it (and please let me know if I could have done it better):

In settings.py

STATIC_ROOT = '/var/www/localhost/htdocs/mysite/static/'
STATIC_URL = '/static/' # default

It seems Django already know where to collect the admin files, you don't need to specify anything in STATICFILES_DIRS unless you need to serve your own custom files (which I don't and thus I had no prior experience with static files in Django).

Then at /var/www/localhost/htdocs/mysite/ type python manage.py collectstatic -l. The -l means to create a symbolic link to all found static files instead of copying it over (saves some space).

Next edit the Apache config file (usually httpd.conf) and add the STATIC_URL information. My config file just for Django looks like this:

Alias /static/ /var/www/localhost/htdocs/mysite/static/
#In the form of...
#Alias STATIC_URL STATIC_ROOT

<Directory /var/www/localhost/htdocs/mysite/static>
    Order deny,allow
    Allow from all
</Directory>

WSGIScriptAlias / /var/www/localhost/htdocs/mysite/mysite/wsgi.py
WSGIPythonPath /var/www/localhost/htdocs/mysite

<Directory /var/www/localhost/htdocs/mysite/mysite>
    <Files wsgi.py>
        Order deny,allow
        Allow from all
    </Files>
</Directory>

Then restart Apache and done!

like image 105
hobbes3 Avatar answered Sep 19 '22 10:09

hobbes3