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

左心房为你撑大大i 提交于 2019-12-08 10:12:02

问题


Thanks in advance for your help.

I'm trying to get Django working on Bluehost. Django's admin site is enabled and accessible at http://www.my-domain.com/admin/. However, the whole admin site looks like plain html with no style or images - unlike what I see when using Django's own server (with $ python manage.py runserver).

After looking around for a solution I tried the following:

  1. Setting the right values for STATIC_ROOT and STATIC_URL in my settings.py (see code below).
  2. Running:

    $ python manage.py collectstatic
    

    (which for some reason seems to copy the files to my project's root folder and not to the static/ folder I specified in settings.py)

  3. Visiting the admin site - still looks like plain html.

Here's an extract from my settings.py file:

import os.path
import sys

# (some more code here)

PROJECT_ROOT = os.path.normpath(os.path.dirname(__ file__))
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    # empty
)
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

And here's how the .htaccess file in my public_html folder looks:

AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{REQUEST_URI} !^/static/
RewriteRule ^(.*)$ my_fcgi_file.fcgi/$1 [QSA,L]

Note the following:

  • I don't have access to httpd.conf.
  • 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). I tried copying them manually into this folder, but the admin site still looks like plain html.

Please let me know if you need any additional information.

Any help will be much appreciated :)

Thanks!


回答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.




回答2:


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/.



来源:https://stackoverflow.com/questions/14883036/djangos-admin-is-missing-css-images-etc-unable-to-properly-set-up-static-fi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!