[Answer]-Django's admin is missing css, images, etc – unable to properly set up static files on shared host

1👍

In your .htaccess file you are filtering out requests to ^/static/, so your rewrite rules won’t apply. If you copy your static files are at public_html/static/, you should see the admin css.

Otherwise, if you want to point the requests to your static files directory

Try removing

RewriteCond %{REQUEST_URI} !^/static/

and adding a rule to point requests to where your static files live

RewriteRule ^(static/.*)$ path/to/static/files [L]

The [L] component means last and is to tell apache not to run the other rules for paths that start with static.

0👍

I also had problems with this issue and was able to solve it so I wanted to share this.

Whenever I use “python manage.py collectstatic” it copies the files in
my project’s root folder, not in my project’s static folder (which is
the folder I specified in STATIC_ROOT).

you specified:

PROJECT_ROOT = os.path.normpath(os.path.dirname(__ file__))
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')

There is a space between __ and file__. Not sure if this is just a copy & past problem but if Django fails to read the settings, this might be the issue.

The more interesting part was how to figure out what RewriteRule to use. Some suggested a combination of Alias for the static files and RewriteRulefor the cgi. However, this doesn’t work since Alias is Evaluated after Rewrite and the statics must be processed in advance so the static urls is not passed to the cgi.

It is important to understand where everything is located because the .htaccess file searches for files relatively to its own location. So here is what it looks for my specific environment.

I’m running Django on a Virtual Server with ssh access which means I don’t have access to /srv/www e.g. So everything is location in my home directory:

/home/<user>/

There is my user www root, including .htaccess and static files:
/home//html
/home//html/.htaccess
/home//html/static

This is the two important lines within setting.py.

STATIC_URL = '/static/'
STATIC_ROOT = '/home/<user>/html/static/'

I don’t have STATICFILES_DIRS and STATICFILES_FINDERS because I use the default in Django 1.6.1.

When I run

python manage.py collectstatic

everything from my app’s and projects static directories are beeing copied to STATIC_ROOT. STATIC_URLis the string Django prefixes urls that refer to static files. So when the Apache web server receives a URL like http://www.mydomain.com/static/mystyle.css, it needs to know that is must not redirect it to Django and where to look for the file mystyle.css.

So this is my .htaccess:

RewriteEngine on
RewriteRule ^static/(.*)$ static/$1 [L]
RewriteRule ^(.*)$ /fcgi-bin/<django-fcgi-file>/$1 [QSA,L]

As you see, I’m using fcgi, other may use wsgi but that’s not the issue. More important, I’ve added this one line RewriteRule ^static/(.*)$ static/$1 [L].

It tells Apache, that whenever a URL starts with static (no prefixed slash!), it should redirect everything that follows (.*) (which will be referenced as $1) to the directory static and append $1 to it. The [L] as explained by Tim Edgar tells Apache to prefer this rule.

This did the trick from me. Some related answer suggested /static/$1/ (with prefixed slash) which did not work (because its not a relative path). In my case, the static directory is located within the htmldirectory where also .htaccess is. So a relative path works here.

If I would use the RewriteRule based on Tim’s answer for my environment it should look like this:

RewriteRule ^(static/.*)$ $1 [L]

The target path is simple $1 because the match already includes the word static/.

👤jaw

Leave a comment