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

What Does Django static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) Actually DO?

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

If you use django.contrib.staticfiles as explained above, runserver will do this automatically when DEBUG is set to True. If you don’t have django.contrib.staticfiles in INSTALLED_APPS, you can still manually serve static files using the django.views.static.serve() view.

This is not suitable for production use! For some common deployment strategies, see Deploying static files.

For example, if your STATIC_URL is defined as /static/, you can do this by adding the following snippet to your 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)

Note

This helper function works only in debug mode and only if the given prefix is local (e.g. /static/) and not a URL (e.g. http://static.example.com/).

Also this helper function only serves the actual STATIC_ROOT folder; it doesn’t perform static files discovery like django.contrib.staticfiles.

我的解读

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

我的问题

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

例子

settings.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'

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

然后我做:python manage.py collectstatic

此时,我的 urls.py 中是否包含以下内容似乎并不重要 - 我的静态文件仍在加载,但我不知道它们是否来自我的项目静态目录或我的 STATIC_ROOT (c:/lkdsjfkljsd_cdn):

if settings.DEBUG is True:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

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

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

*编辑(添加 HTML 图片)

我认为你混淆了一些东西。让我澄清一下。

static:

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

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

它的作用是去掉前缀左边的正斜杠(即将/static/转换为static/),然后有一个视图(即serve)谁来拉取文件。

serve:

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

runserver:

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

collectstatic:

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

finally:

回答您的问题:

  1. 不,您不必将其放入您的代码中,除非您不在 INSTALLED_APPS.

    [=82= 中添加 django.contrib.staticfiles ]
  2. 你不需要。 STATIC_ROOT 用途不同

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

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

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