STATICFILES_DIR、STATIC_ROOT和MEDIA_ROOT的区别

142

这三个静态URL有什么区别?

我不确定是否正确,我正在使用MEDIA_ROOT来存储我上传的照片(通过models.ImageField()

然而,我在admin.py中为我的管理页面创建了一个JS脚本,并定义了媒体如下:

....
class Media:
      js = ('/admin/custom.js', )

以及我的settings.py文件:

 ....
 STATIC_ROOT = "/home/user/project/django1/top/listing/static"

我将custom.js添加到STATIC_ROOT/admin/custom.js,但它没有起作用,会抛出404未找到错误。

随后我将STATIC_ROOT更改为STATICFILES_DIRS,然后它就可以工作了!

....
STATICFILES_DIRS = "/home/user/project/django1/top/listing/static"

所以,我不明白这里到底发生了什么。事实上,我并不理解STATIC_ROOTSTATICFILES_DIRS之间的区别。

目前我正在我的虚拟环境中测试Django,还没有部署,这是STATIC_ROOT无法正常工作的原因吗?


3
请参阅我制作的有关生产环境中静态文件工作原理的图形:http://djangodeployment.com/2016/11/21/how-django-static-files-work-in-production/ - Antonis Christofides
4个回答

252

开发

STATIC_ROOT在开发过程中没有任何作用,只有在部署时才需要。

在开发过程中,STATIC_ROOT什么也不做。你甚至不需要设置它。Django会自动查找每个应用程序目录下的静态文件(myProject/appName/static)并提供服务。

这是由manage.py runserverDEBUG=True时完成的魔术。

部署

当你的项目上线时,情况就有所不同。最可能的情况是使用Django提供动态内容,而静态文件则由Nginx提供服务。为什么呢?因为Nginx非常高效,可以减轻Django的工作负担。

这就是STATIC_ROOT派上用场的地方,因为Nginx对于你的Django项目一无所知,也不知道在哪里查找静态文件。

所以你要设置STATIC_ROOT = '/some/folder/',并告诉Nginx在/some/folder/中查找静态文件。然后运行manage.py collectstatic,Django将把所有应用程序中的静态文件复制到/some/folder/中。

额外的静态文件目录

STATICFILES_DIRS用于包含附加的目录供collectstatic查找。例如,默认情况下,Django无法识别/myProject/static/。所以你可以自己进行包含。

示例

STATIC_URL = '/static/'

if not DEBUG:
    STATIC_ROOT = '/home/django/www-data/example.com/static/'

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

50
最好的STATIC_ROOT等解释应该清晰而简明。这就是 Django 文档中应该包含的内容。 - Homunculus Reticulli
3
@Max Malysh,这就是我们应该有的回答水平。明白了!A+ - adhg
2
非常阐明。谢谢! - MadPhysicist
1
谢谢!这个清晰的答案比 Django 文档中混乱的文本好多了。 - JMJ
2
你甚至不需要添加STATICFILES_DIRS(如果您没有其他目录要提供文件),您可以在urls.py中的urlpatterns中添加static(...)函数,正如文档中所述,它仅在Debug模式下工作。 - Konstantin Kozirev

165

您可以在Django文档中找到这些设置。以下是我自己的定义和引用文档:

  • MEDIA_ROOT是使用FileField上传的文件所存储的文件夹。

    绝对文件系统路径,用于存放用户上传的文件的目录。

  • STATIC_ROOT是静态文件在使用manage.py collectstatic后存储的文件夹。

    collectstatic将收集静态文件以进行部署的目录的绝对路径。

    如果启用了staticfiles contrib app(默认情况下),则collectstatic管理命令将把静态文件收集到此目录中。有关使用方法的详细信息,请参见有关管理静态文件的howto。

  • STATICFILES_DIRS是Django将搜索附加静态文件的文件夹列表,除了每个已安装应用程序的static文件夹之外。

    如果启用了FileSystemFinder查找器,则此设置定义了staticfiles app将遍历的其他位置,例如,如果您使用collectstaticfindstatic管理命令或使用静态文件服务视图。

在您的设置中,应该有:
MEDIA_ROOT = os.path.join(BASE_DIR, "media/")
STATIC_ROOT = os.path.join(BASE_DIR, "static/")

# Make a tuple of strings instead of a string
STATICFILES_DIRS = ("/home/user/project/django1/top/listing/static", )

...其中:

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

现在按照默认的Django settings.py文件定义。


3
我认为这个回答很清晰明了,虽然我感觉这个问题已经被问过了。 - Ian Clark
4
@MaximeLorant,说实话,你的解释比Django文档更好。 - Eje
2
@MaximeLorant 的回答构造得非常好。正如 Jee 所提到的,比文档本身更清晰明了。 - Llanilek

30

STATICFILES_DIRSSTATIC_ROOT之间的区别在于:

STATICFILES_DIRS可以包含其他目录(不一定是应用程序目录)中的静态文件,当运行 collectstatic 命令时,这些静态文件将被收集到你的 STATIC_ROOT 中。这些静态文件将会由你的 Web 服务器提供,并从你的 STATIC_ROOT 目录中提供服务。

如果您希望使用当前位于STATIC_ROOT中的文件,则需要将这些文件移动到另一个目录,并将该目录放入STATICFILES_DIRS中。你的 STATIC_ROOT 目录应该是空的,所有静态文件应该被收集到该目录中。

MEDIA_ROOT是存储媒体文件(所有上传的文件)的位置,例如图片、文件等。


5
谢谢你的答复。希望我可以选择多于一个答案来回答这个问题。你的答案对我也非常有帮助。 - dev-jim

0
class Media:
      js = ('/admin/custom.js', )

但它没有起作用。抛出404未找到错误。 文件路径中前导斜杠的原因之一是404错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接