Django 应用程序无法识别静态文件
Posted
技术标签:
【中文标题】Django 应用程序无法识别静态文件【英文标题】:Django app doesn't recognize static files 【发布时间】:2018-03-13 05:39:50 【问题描述】:我有一个Django
应用程序,我无法在其中加载静态文件。我的模板已完美加载,但无法加载 CSS 和 JS 文件。这是我的文件:
zeinab@ZiZi:~/Desktop/MyProject$ tree
.
├── __init__.py
├── manage.py
├── myapp
│ ├── __init__.py
│ ├── lib
│ │ ├── decorators.py
│ │ ├── dorsa_forms.py
│ │ ├── __init__.py
│ │ └── utils.py
│ ├── log
│ ├── media
│ │ └── admin
│ │ └── background_login
│ │ └── bg1.jpg
│ ├── settings.py
│ ├── static
│ │ ├── calendar.js
│ │ └── inbox.css
│ ├── templates
│ │ ├── 404.html
│ │ ├── base.html
│ │ └── index.html
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
└── requirements.txt
8 directories, 18 files
当我 runserver
时,每个 CSS 和 JS 文件都会得到 "GET /static/file/url HTTP/1.1" 404 1265
。这是 MyProject/manage.py:
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
这是 MyProject/myapp/settings.py:
import os
from django.contrib.messages import constants as messages
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',
'sorl.thumbnail',
'myapp.lib',
)
MIDDLEWARE_CLASSES = (
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
SITE_ID = 1
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
ROOT_URLCONF = 'myapp.urls'
TEMPLATES = [
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "templates")],
'APP_DIRS': True,
'OPTIONS':
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n',
],
,
,
]
WSGI_APPLICATION = 'myapp.wsgi.application'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
STATIC_ROOT = '/myapp/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = '/media/'
LOG_PATH = os.path.join(BASE_DIR, 'log')
DEBUG = True
这是MyProject/myapp/urls.py:
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from .views import default
urlpatterns = [
url(r'^$', default, name='default'),
url(r'^admin/', admin.site.urls),
]
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
这是MyProject/myapp/wsgi.py:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
application = get_wsgi_application()
编辑 1:
我已将 MyProject/myapp/urls.py 更改为以下内容:
from django.conf import settings
from django.conf.urls import include, url
from django.views import static
from django.contrib import admin
from .views import default
urlpatterns = [
url(r'^$', default, name='default'),
url(r'^admin/', admin.site.urls),
url(r'^public/(?P<path>.*)$', static.serve,
'document_root': settings.MEDIA_ROOT
, name='url_public'),
]
我最终得到了相同的结果。
编辑 2:
我也尝试使用urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
而不是urlpatterns += staticfiles_urlpatterns()
,然后尝试使用collectstatic
; collectstatic
成功完成,但仍打开 URL 返回 "GET /static/file/url HTTP/1.1" 404 1265
。
【问题讨论】:
【参考方案1】:替换
urlpatterns += staticfiles_urlpatterns()
通过
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
staticfiles_urlpatterns()
仅用于调试以显示静态文件的视图。正如https://docs.djangoproject.com/en/1.11/ref/contrib/staticfiles/ 中提到的,它不应在生产中使用。
注意:STATIC_ROOT
和 MEDIA_ROOT
仅在您收集静态数据时使用(collectstatic
和 manage.py
)。它指定了存储静态和媒体文件的绝对路径(通常是/var/www/myapp/static
和/var/www/myapp/media
)
【讨论】:
【参考方案2】:在您的urls.py
中,您忘记说明如何“计算”静态路由文件。
而不是这个:
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
试试这个:
from django.views import static
urlpatterns = [
# [...]
url(r'^public/(?P<path>.*)$', static.serve,
'document_root': settings.MEDIA_ROOT
, name='url_public'),
]
在您的模板文件中(您没有提供示例),尝试:
% load static %
<h1>% static 'calendar.js' %</h1>
不要忘记使用 PyCharm,因为它对这些事情有很大帮助(它可以识别路径,并且您会在模板文件中获得自动完成功能 (Ctrl+Space))。
【讨论】:
当我runserver
时,我得到AttributeError: 'function' object has no attribute 'serve'
。您是否使用特定版本的Django
?我最新的是1.11.5
。
使用 PyCharm,转到“static”一词,然后按“Alt-enter”“enter”,这样 PyCharm 就会在您的 urls 文件顶部添加正确的“import”,或者手动添加它:from django.views import static
重点是:我使用static
来自django.conf.urls.static
,正如您在问题中看到的那样,但您指的是static
来自django.views
。请在您的回答中提及这一点。
@ZeinabAbbasi 好的,我已经编辑了我的答案,感谢您的建议。它是否有效,我是否回答/让您走上了正确的道路?
我仍然得到我在问题中提供的404
。以上是关于Django 应用程序无法识别静态文件的主要内容,如果未能解决你的问题,请参考以下文章
我无法在 django 中使用“静态”模板导入 css 文件
为啥我的 django 模板无法识别我在 views.py 文件中设置的 url 参数?