Django Apps应该如何捆绑静态媒体?

时间:2010-01-14 12:15:56

标签: python django web-applications

背景:

我第一次开始使用Django,这也是我第一次涉足网络开发。我只是陷入了整个“服务静态媒体”的问题。在花了一段时间查看所有文档和StackOverflow问题后,我想我理解它应该如何工作(即MEDIA_ROOT,MEDIA_URL,更新urls文件等)。

我的问题

好的,所以这是我不确定的部分。 Django应用程序应该是“可插拔的”,即我可以将应用程序从一个项目移动到另一个项目。那么,这些应用程序应该如何捆绑静态媒体?

例如,假设我有一个“foo”应用程序,它具有加载一些css /图像文件的模板。我应该把这些文件放在哪里,以便在我加入申请后它们会自动获得服务?

我看到的唯一解决方案是,安装应用程序必须包括将其静态媒体复制到服务该媒体的服务器上某个位置的额外步骤。

这是接受的方式吗?它包括一个额外的步骤,但也许这是处理web-dev的标准(我是新的,所以我真的不知道)。

此外,如果是这样,有没有一种标准方法来收集我的所有静态媒体,以便更容易知道我需要提供什么? (即,在应用程序中有一个名为“media”的文件夹或其他内容是否标准?)。

谢谢,

3 个答案:

答案 0 :(得分:9)

惯例是将静态媒体放在app中的media / appname /或static / appname /中(类似于模板)。

要在项目中使用媒体附带的应用,我强烈建议您使用django-staticfiles。它将通过替换django.views.static.serve的视图自动为开发中的媒体(包括应用程序中的媒体)提供服务,并且它附带了build_static管理命令,该命令将所有应用程序中的媒体复制到单个目录中以便在生产中投放。

更新:django-staticfiles有become part of Django 1.3。它现在希望应用媒体存在于应用的“静态/”子目录中,而不是“媒体/”。管理命令现在是“collectstatic”。

答案 1 :(得分:2)

我所知道的唯一一个没有任何干预的应用程序是相当精彩的django-debug-toolbar,虽然可以说这不是一个很好的例子,因为它是专门为调试模式设计的应用程序。 / p>

它处理它的方式是它通过Django本身为其媒体提供服务 - 请参阅urls.py的来源:

url(r'^%s/m/(.*)$' % _PREFIX, 'debug_toolbar.views.debug_media'),

一般来说,根据this comment from the documentation,这是一个坏主意(你不想通过Django提供静态文件):

  

[通过Django提供静态文件]效率低下   不安全的。不要在a中使用它   生产设定。仅用于此   发展。

显然,django-debug-toolbar只用于开发,所以我认为它的部署方法很有意义,但这是一个例外。

一般来说,我知道这样做的最佳方式是在您的媒体存储到应用代码内的媒体的任何地方创建符号链接。例如,在您的应用中创建一个名为media的文件夹,然后要求用户安装您的应用,以便从其媒体目录添加符号链接,或复制整个内容。

答案 2 :(得分:2)

我通常把应用媒体放在./apps/appname/static(我的应用程序驻留在应用程序子文件夹中)

然后我在apache的vhost中有类似的东西:

AliasMatch ^/apps/([^/]+)/static/(.*) /home/django/projectname/apps/$1/static/$2
<DirectoryMatch "^/home/django/projectname/apps/([^/]+)/static/*">
        Order deny,allow
        Options -Indexes
        deny from all
        Options +FollowSymLinks
        <FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf|txt|htm|html|json)$">
                allow from all
        </FilesMatch>
</DirectoryMatch>

我的urls.py中也有这个用于dev服务器(仅用于调试):

def statics_wrapper(request, **dict):
    from django.views import static
    return static.serve(request, dict['path'], document_root = os.path.join(settings.BASE_DIR, 'apps', dict['app'], 'static'), show_indexes=True)
urlpatterns += patterns('', (r'^apps/(?P<app>[^/]+)/static/(?P<path>.+)$', statics_wrapper))

这非常方便因为statics url只是映射到文件系统,例如:

http://wwww.ecample.com/apps/calendar/static/js/calendar.js位于[BASE_DIR] /apps/calendar/static/js/calendar.js

希望这会有所帮助