【问题标题】:Static files loading in production but not development在生产中加载静态文件,但在开发中不加载
【发布时间】:2019-03-03 19:31:08
【问题描述】:

通常我有这个问题正好相反!

在我的开发环境中,我的 Django 应用程序不会加载我的一些静态文件,特别是我自己添加的那些:也就是说,我添加到我的应用程序的两个包(adminckeditor)是两者都加载正常,但是我自己创建和链接的两个文件夹(imgcss)没有找到。这是我的目录的地图:

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

如前所述,ckeditoradmin 可以正常加载,而其他的则不能。以下是调试模式下runserver 输出的示例(static/css/base.css 处的文件存在于我的文件树中):

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

这里有一些其他可能感兴趣的信息:

  • 它在生产中运行良好!我认为这是因为我的 apache 配置中有专用别名,但这并不能解释为什么 adminckeditor 有效。
  • 我以几乎相同的方式路由媒体(请参阅下面的设置文件),并且在开发中运行良好。
  • 我按照 Django 文档的说明使用模板标签 {% load static %}。在旧版本中,我使用了{% load staticfiles %},我也尝试过。
  • 我在两种环境中都运行过collectstatic
  • 使用DEBUG=False 运行在生产环境中运行良好(所有静态文件加载),但在DEBUG=False 开发环境中根本不加载静态文件。这是意料之中的,因为在开发中我没有网络服务器来处理这个问题(澄清一下,我通常在调试模式下运行服务器,但尝试关闭和打开此设置看看发生了什么变化)

为了帮助任何人调试我的问题,以下是一些相关的摘录文件:

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)

【问题讨论】:

  • 你跑collectstatic了吗?
  • @nik_m 是的,在这两种环境中 - 我将把它添加到问题中
  • 在您的 urls.py 中,ckeditor 路径没有/ 尝试给它看看。
  • ckeditor 的静态文件已在两种环境中正常加载。添加/ 似乎对ckeditor 的静态文件或未加载的静态文件都没有影响。
  • 好的,然后再给 static_root 和 media_root 一个建议,STATIC_ROOT = os.path.join(BASE_DIR, 'static/')MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') 试试这个。

标签: python python-3.x django static-files


【解决方案1】:

这是在 django 中处理静态文件的一种简单方法(如果您使用 Django 默认选项,则开箱即用):

  1. 永远不要将任何东西自己放入您指定为STATIC_ROOT的文件夹中
  2. 将特定于应用的静态文件放入应用内的文件夹static
  3. 对于不直接属于应用程序的静态文件,在您的项目中创建文件夹static_files 并添加到您的设置中:STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_files'),]显然你可以选择其他名字,static_files 只是一个建议。
  4. 用于生产运行collectstatic,以便 Django 收集您的静态文件(从第 2 点和第 3 点开始)并将它们放入您在 1 中创建的文件夹中。

如果您处于调试模式,则在第 3 步之后就完成了。


在您的情况下,问题在于您将静态内容放入了 STATIC_ROOT,这是 Django 在调试模式下不会查找内容的文件夹。 adminckeditor 工作是因为它们遵循第 2 步,因此它们的静态文件实际上来自已安装应用程序的文件夹,而不是在调试模式下来自您的 static 文件夹。


所以,这是解决问题的方法

  • 从上方执行第 3 步。
  • 将您的文件夹 imgcss 移动到在步骤 3 中创建的文件夹中。
  • (可选)擦除您的 STATIC_ROOT 文件夹。

【讨论】:

    【解决方案2】:

    由于您的应用列表中有'django.contrib.staticfiles',当 DEBUG 为 True 时,Django 实际上不会从 STATIC_ROOT 加载文件。

    当启用 DEBUG 时,Django 使用 STATICFILES_FINDERS 选项,默认为:

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

    FileSystemFinder 将查找存储在 STATICFILES_DIRS 设置中的文件 AppDirectoriesFinder 正在每个应用程序的 static 子目录中查找文件。

    这就是文件夹 admin 和 ckeditor 工作的原因 - 当 DEBUG 为 True 时,Django 根本不使用您的 /root/static 文件夹。相反,它通过 AppDirectoriesFinder 从应用程序static 子目录中获取文件。 类似于 .../3.5/lib/python3.5/site-packages/django-ckeditor/static/...

    当您运行collectstatic 命令时,它会收集 STATICFILES_FINDERS 可以找到的所有静态文件并将它们复制到您的 STATIC_ROOT (/root/static/) 中,如果 DEBUG 为 False,Django 只使用此文件夹而不是 STATICFILES_FINDERS

    那么你如何使它在启用调试的情况下工作。只需创建一个文件夹并将其添加到 STATICFILES_DIRS 中,如下所示:

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

    您还可以删除/root/static/ 中的所有文件,您无需在此文件夹中手动创建任何内容,collectstatic 会自动为生产环境执行此操作。

    【讨论】:

      【解决方案3】:

      您的 urlpatterns 是正确的,这意味着问题很可能是设置文件中的settings.DEBUG = False。确保settings.DEBUGTrue,并且应该加载静态文件。您可以使用manage.py shell 并检查DEBUG 标志的值来验证这一点。

      唯一要查找的其他问题是您是否通过验证ROOT_URLCONF 设置以及您的BASE_DIR 是否指向static 目录的父目录来指向您的设置中的正确urls 文件。这两个值也可以在shell 中验证。

      例如,如果您的设置文件位于/path/to/root/blog/settings.py,那么您将BASE_DIR 设置为:

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

      【讨论】:

      • 原谅我不清楚:虽然我在附加信息中谈到settings.DEBUGFalse,但在开发中通常设置为True。在上面提到的情况下,我尝试将其更改为False 以查看它会产生什么效果,并且行为基本上符合预期。我一定会在问题中澄清这一点。为了确认,我检查了manage.py shell,并在运行服务器时强制出现404错误:两者都表示DEBUG=True。此外,我的BASE_DIR 与您的建议完全相同 - 我会确保问题也反映了这一点。
      【解决方案4】:

      我在本地文件方面也遇到了一些问题,这对我的情况有所帮助。

      我确实将我的静态文件存储在 S3 上,但您可以调整图像位置 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/'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-17
        • 2021-05-20
        • 1970-01-01
        • 2015-08-22
        • 1970-01-01
        相关资源
        最近更新 更多