Django static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 实际上做什么?

Jar*_*rad 12 python django django-settings

我正在使用 Django 2.2。来自 Django管理静态文件 文档

如果您按上述说明使用 django.contrib.staticfiles,则当 DEBUG 设置为 True 时,runserver 将自动执行此操作。如果您在 INSTALLED_APPS 中没有 django.contrib.staticfiles,您仍然可以使用 django.views.static.serve() 视图手动提供静态文件。

这不适合生产使用!有关一些常见的部署策略,请参阅部署静态文件。

例如,如果您的 STATIC_URL 定义为 /static/,您可以通过将以下代码段添加到您的 urls.py 来实现:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Run Code Online (Sandbox Code Playgroud)

笔记

此辅助函数仅在调试模式下工作,并且仅当给定前缀是本地前缀(例如 /static/)而不是 URL(例如 http://static.example.com/)时。

此外,此辅助函数仅服务于实际的 STATIC_ROOT 文件夹;它不会像 django.contrib.staticfiles 那样执行静态文件发现。

我的解释

  1. static是一个辅助函数,用于STATIC_ROOT 在开发过程中提供文件(这是真的吗?)
  2. 静态仅适用于debug = True
  3. static仅适用于本地前缀,如STATIC_URL = '/static/'
  4. DEBUG设置为 True 并且我按照文档中的说明使用和设置 staticfiles 应用程序时,如果我python manage.py runserver启动本地服务器,将自动处理静态文件的服务(真的??)

我的问题

  1. 添加static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)到您项目的urls.pyDO 中究竟有什么作用?
  2. 这是真的,从本地静态文件STATIC_ROOT目录?为了测试这个理论,在运行之后collectstatic,我删除了static目录以查看静态文件是否仍然可以正常加载(来自 STATIC_ROOT)并且它们不!为什么?
  3. 如何验证Django 正在从我的 STATIC_ROOT 位置加载静态文件...而不是我的项目和应用程序中的静态目录?
  4. 为什么加入static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)urlpatterns必要的,如果Django的静态文件自动(在文档中提到的)?

例子

Django 项目示例

设置.py

DEBUG = True

...

INSTALLED_APPS = [
    'django.contrib.admin',
    ...
    'django.contrib.staticfiles',
    'puppies.apps.PuppiesConfig'
]

...

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

STATIC_ROOT = 'c:/lkdsjfkljsd_cdn'
Run Code Online (Sandbox Code Playgroud)

在我所有的模板中,我都使用{% load static %}.

然后我这样做: python manage.py collectstatic

STATIC_ROOT

在这一点上,我是否有以下内容似乎并不重要urls.py- 我的静态文件仍在加载但我不知道它们是来自我项目的静态目录还是来自我的 STATIC_ROOT (c:/lkdsjfkljsd_cdn ):

if settings.DEBUG is True:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Run Code Online (Sandbox Code Playgroud)

最后,如果我删除项目中的那些静态目录,所有 css、js 和图像都不起作用,这让我相信我的 Django 项目正在从项目的静态目录加载静态文件,而不是 STATIC_ROOT。

那么,再一次,我如何告诉 Django 从我的 STATIC_ROOT 位置加载静态文件......而不是我的项目和应用程序中的静态目录?或者,我是否误解了 Django 不应该从本地 STATIC_ROOT 位置加载文件?

*编辑(添加 HTML 图像)

HTML

rud*_*dra 7

我认为你混淆了几件事。让我澄清一下。

static:

根据文档,它提供了用于提供静态文件的 URL 模式。如果你去implementation,那么你会看到:

return [
        re_path(r'^%s(?P<path>.*)$' % re.escape(prefix.lstrip('/')), view, kwargs=kwargs),
]
Run Code Online (Sandbox Code Playgroud)

它的作用是,它从前缀左侧删除正斜杠(即转换/static/static/),然后有一个视图(即serve)谁执行拉取文件。

serve:

此功能执行服务文件。它将从文档根目录提供文件。

runserver:

runserver命令运行 django 开发服务器。如果您已django.contrib.staticfiles安装在 中INSTALLED_APPS,那么它将自动提供静态文件。如果您不想提供静态服务,请使用runserver --nostatic. collectstaticSTATIC_ROOT与此命令无关。

collectstatic

该命令从不同的收集所有静态文件STATIC_DIRS,并把它们在其中被定义的文件夹STATIC_ROOTcollectstatic在生产部署中非常有用,当您使用像 NGINX 或 Apache 等反向代理服务器时。 NGINX/Apache/Varnish 使用该文件夹(collectstatic 存储静态文件的位置)作为根目录并从中提供静态服务。不建议runserver在生产中使用。你可以使用 gunicorn/uwsgi 来服务 django。但是 gunicorn/uwsgi 不提供静态文件,因此使用反向代理服务器来提供静态文件。

finally:

回答您的问题:

  1. 不,你不必把它放在你的代码中,除非你没有django.contrib.staticfiles在你的INSTALLED_APPS.

  2. 你不需要。STATIC_ROOT 用于不同的目的

  3. 它不是。但是为了提供媒体文件,您可以添加以下模式:

    if settings.DEBUG:
        urlpatterns += [
            re_path(r'^media/(?P<path>.*)$', serve, {
                'document_root': settings.MEDIA_ROOT,
            }),
        ]
    
    Run Code Online (Sandbox Code Playgroud)

在生产中,媒体文件也应该由反向代理服务器提供服务。