简体   繁体   中英

Static files loading in production but not development

Usually I have this issue exactly the other way around!

In my development environment my Django app will not load some of my static files, specifically ones that I have added myself: that is, the two packages I've added to my app ( admin and ckeditor ) are both loading up fine, but two of the folders I've created and linked myself ( img and css ) are not being found. Here's a map of my directory:

root
 |-- blog    (this is the name of my app)
 |-- mysite  (name of my site)
      |-- settings.py
      |-- urls.py
 |-- media
 |-- static
      |-- admin
      |-- ckeditor
      |-- css
      |-- img

As stated, ckeditor and admin load fine while the others do not. Here's an example from the runserver output in debug mode (the file at static/css/base.css exists in my file tree):

GET /static/ckeditor/ckeditor/ckeditor.js HTTP/1.1" 200 690627
GET /static/admin/css/fonts.css HTTP/1.1" 200 423
GET /static/admin/css/widgets.css HTTP/1.1" 200 10340
GET /static/css/base.css HTTP/1.1" 404 1761
GET /static/img/brand.png HTTP/1.1" 404 1764

Here's some other information which may be of interest:

  • It works fine in production! I assumed this was because I had dedicated aliases in my apache config, but that doesn't explain why admin and ckeditor work.
  • I have routed media in much the same way (see the settings file below) and that works fine in development.
  • I am using the template tag {% load static %} as instructed by the Django docs. In older versions I used {% load staticfiles %} and I've tried that too.
  • I have run collectstatic in both environments.
  • Running with DEBUG=False works fine in production (all the static files load) but no static files load at all when DEBUG=False in development. This is to be expected though, since in development I don't have a web server to handle this (to clarify, I usually run the server in debug mode, but have tried turning this setting off and on to see what changes occur)

In an effort to help anyone debug my problem, here are some relevant excerpts files:

settings.py

DEBUG = True
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
    'ckeditor',
    'ckeditor_uploader',
]
...
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('', include('blog.urls')),
    path('admin/', admin.site.urls),
    path('ckeditor', include('ckeditor_uploader.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

This is an easy approach for handling static files in django (that works out of the box if you use Django default options):

  1. Don't ever put anything yourself into the folder you specify as STATIC_ROOT .
  2. Put static files specific to an app into the folder static inside the app.
  3. For static files that do not directly belong to an app, create the folder static_files within your project and add to your settings: STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_files'),] . Obviously you can choose another name, static_files is just a suggestion.
  4. For production run collectstatic so that Django collects your static files (from points 2. and 3.) and puts them into the folder you created in 1.

If you are in debugging mode you are done after step 3.


In your case , the problem was that you put static content into the STATIC_ROOT which is a folder Django wont look for content in debugging mode. admin and ckeditor work because they follow step 2., thus their static files actually come from the folder of the installed app and not from your static folder when in debugging mode.


So, here is how to fix your issue :

  • do step 3. from above.
  • move your folders img and css to the folder created in step 3.
  • (optional) wipe your STATIC_ROOT folder.

Since you have 'django.contrib.staticfiles' in your apps list, Django actually does NOT load files from STATIC_ROOT when DEBUG is True.

When DEBUG is enabled Django uses STATICFILES_FINDERS option that by default is:

[
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

FileSystemFinder will find files stored in the STATICFILES_DIRS setting and AppDirectoriesFinder is looking for files in a static subdirectory of each app.

That's why folders admin and ckeditor work - Django doesn't use your /root/static folder at all when DEBUG is True. Instead it gets files by AppDirectoriesFinder from apps static subdirectories. Something like .../3.5/lib/python3.5/site-packages/django-ckeditor/static/...

When you run collectstatic command it collects all static files that STATICFILES_FINDERS can find and copies them into your STATIC_ROOT (/root/static/) and if DEBUG is False Django just uses this folder instead of STATICFILES_FINDERS

So how you can make it work with debug enabled. Just create a folder and add it to STATICFILES_DIRS like this:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'some_new_static_folder'),
]

Also you can delete all files from /root/static/ you don't need to create anything inside this folder manually, collectstatic will do it automatically for production.

Your urlpatterns are correct, which means the issue is most likely that settings.DEBUG = False in the settings file. Make sure settings.DEBUG is True , and the static files should load. You can verify this by either using manage.py shell and checking the value of the DEBUG flag.

The only other issues to look for is whether you are pointing to the correct urls file in your settings by verifying the ROOT_URLCONF setting and whether your BASE_DIR points to the parent directory of the static directory. Both values can also be verified in shell .

For example, if your settings file is located in /path/to/root/blog/settings.py , then you set BASE_DIR as :

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

I also had some issues with local files and this help my situation.

I do store my static files on S3 but you can adjust your image location URL.

if DEBUG == False:
    STATICFILES_LOCATION = 'static'
    STATIC_URL = "//%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
    MEDIAFILES_LOCATION = 'media'
    MEDIA_URL = "//%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
else:
    MEDIA_URL = '/media/'
    STATIC_URL = '/static/'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM