在Django的debugging和生产中configuration静态文件的最常见方法是什么?

在debugging模式下开发Django应用程序时,我使用以下代码提供静态文件:

if settings.DEBUG: urlpatterns += patterns('', (r'^m/(?P<path>.*)$', serve, { 'document_root' : os.path.join(os.path.dirname(__file__), "media") }) ) 

我使用nginx作为前端服务器在生产模式下使用以下nginxconfiguration我的静态文件:

  location m/ { root /path/to/folder/media/; } 

这似乎是次优的,因为我必须在媒体目录中创build一个“m”文件夹。 我想知道其他人的Django / nginxconfiguration文件是什么样子。 具体来说,你可以剪切粘贴nginx.confg和urls.py(settings.DEBUG == True)

谢谢。

使用Django 1.3 django.contrib.staticfiles将照顾在开发过程中为您提供的一切。 你不需要在urls.py中做任何特别的事情。 在Django 1.3更新之后,我为自己写了一个小小的指南,涵盖了要使用的设置:

 # idiom to get path of project import os PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) # url prefix for user uploaded files, stuff that django has to serve directly MEDIA_URL = '/media/' # url prefix for static files like css, js, images STATIC_URL = '/static/' # url prefix for *static* /admin media ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/' # path to django-served media MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media') # path used for collectstatic, *where the webserver not django will expect to find files* STATIC_ROOT = '/home/user/public_html/static' # path to directories containing static files for django project, apps, etc, css/js STATICFILES_DIRS = ( os.path.join(PROJECT_PATH, 'static'), ) # List of finder classes that know how to find static files in various locations. STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) # Required for all the magic INSTALLED_APPS = ( 'django.contrib.staticfiles', ) 

有关详细信息,请参阅文档: http : //docs.djangoproject.com/en/1.3/howto/static-files/ 。

我使用nginx和uwsgi来为生产服务django应用程序(我使用runserver进行开发)。 我将我的/static/media文件夹(从我的django项目)符号链接到/var/www/vhosts/domain.com/html nginx找到。 您也可以使用collectstatic命令而不是symlinking。 如果找不到静态文件,则会返回到uwsgi(运行django应用程序)。

你可以使用fast-cgi,或者proxy_pass或者你想要的任何东西来代替uwsgi。 我更喜欢uwsgi,因为它具有令人难以置信的功能和卓越的性能。 我运行uwsgi作为守护进程: uwsgi --emperor '/srv/*/*.ini' . uwsgi --emperor '/srv/*/*.ini' 。 这是一个相当新的选项,它告诉uwsgi扫描配置文件的给定路径。 当皇帝uwsgi守护进程发现一个配置文件时,它使用找到的配置启动一个新的uwsgi实例。 如果你改变你的配置,皇帝uwsgi守护进程将会注意到并重新启动你的应用程序。 您也可以使用mod_wsgi来触摸配置文件来重新加载,一旦您拥有最初配置的所有内容,就可以轻松设置新的应用程序。

我遵循的路径约定是:

 /srv/venv/ - virtualenv for project /srv/venv/app.ini - configuration for uwsgi /srv/venv/app.sock - uwsgi sock for django /srv/venv/app.wsgi - wsgi file for uwsgi /srv/venv/proj - django project /srv/venv/proj/settings.py - project settings file /srv/venv/proj/static - static files dir, linked into var/www/vhosts/domain.com/html /srv/venv/proj/static/admin - admin static files, linked as well /srv/venv/proj/media - media files dir /var/www/vhosts/domain.com/html - base directory for nginx to serve static resources from 

这是我的nginx.conf:

 location / { root /var/www/vhosts/domain.com/html; index index.html index.html; error_page 404 403 = @uwsgi; log_not_found off; } location @uwsgi { internal; include /etc/nginx/uwsgi_params; uwsgi_pass unix:/srv/venv/app.sock; } 

我的uwsgi ini文件(你也可以使用xml / yaml / etc):

 [uwsgi] home = /srv/%n pp = /srv/%n wsgi-file = /srv/%n/%n.wsgi socket = /srv/%n/%n.sock single-intepreter = true master = true processes = 2 logto = /srv/%n/%n.log 

你也应该看看gunicorn ,它有非常好的django集成和良好的性能。

我把这个放在这里,以防有人想要一个如何为Apache和WSGI做这个事情的例子。 问题标题的措辞使得它不仅仅覆盖nginx。

Apache / WSGI守护进程

在我的部署中,我决定保留settings.py文件中的数据库连接信息。 相反,我有一个路径/etc/django包含数据库配置的文件。 这在另一个问题的答案中有详细的介绍。 然而,作为一个副作用,我可以检查这些文件的存在和项目在一定的路径,以确定这是否作为部署运行,并在settings.py我定义设置IS_DEVIS_BETAIS_PRODTrueFalse 。 从settings.py找到项目的目录只是:

 # Find where we live. import os BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) 

任何需要进入项目的路径都使用BASE_DIR 。 所以在urls.py ,我最后urls.py

 # Only serve static media if in development (runserver) mode. if settings.IS_DEV: urlpatterns += patterns('', url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), ) 

(我也有另一个URL用于UI测试,不想在测试版或生产版上使用。)

这涵盖了开发服务器的情况。 对于生产,我只需要设置Apache配置来提供静态的东西。 (这是一个低到中等负载的Intranet应用程序,所以我没有像lighttpd这样的轻量级web服务器来提供静态的东西,这与Django文档的建议相反。)因为我使用的是Fedora Core,所以我添加了一个django.conf /etc/httpd/conf.d中的django.conf文件类似于:

 WSGIDaemonProcess djangoproject threads=15 WSGISocketPrefix /var/run/wsgi/wsgi Alias /django/static/ /var/www/djangoproject/static/ Alias /django/admin/media/ /usr/lib/python2.6/site-packages/django/contrib/admin/media/ WSGIScriptAlias /django /var/www/djangoproject/django.wsgi WSGIProcessGroup djangoproject <Directory /var/www/djangoproject> Order deny,allow Allow from all </Directory> <Directory /usr/lib/python2.6/site-packages/django/contrib/admin/media> Order deny,allow Allow from all </Directory> 

IIRC,这里的关键是把你的Alias行放在你的WSGIScriptAlias行之前。 也请确保用户无法下载您的代码; 我通过把静态的东西放在一个static目录中,而不是在我的Django项目中。 这就是为什么BASE_DIR给出了包含 Django项目目录的目录。

您可以省略WSGISocketPrefix行。 我有它,因为管理员想要在非默认位置的套接字。

我的WSGI文件位于/var/www/djangoproject/django.wsgi (即Mercurial存储库中的/django.wsgi ),包含如下内容:

 import os import sys os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings' os.environ['DB_CONFIG'] = '/etc/django/db_regular.py' thisDir = os.path.dirname(__file__) sys.path.append(thisDir) sys.path.append(os.path.join(thisDir, 'djangoproject')) sys.path.append(os.path.join(thisDir, 'lib')) import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() 

关于WSGI守护进程的touch django.wsgi是你只需要touch django.wsgi来重新启动你的Django WSGI守护进程; 您不需要重新加载或重新启动Apache服务器。 这使得管理员开心。

最后,因为我的/var/www/djangoproject只是一个Mercurial回购,我在/var/www/djangoproject/.hg/hgrc有以下内容:

 [hooks] changegroup.1=find . -name \*.py[co] -exec rm -f {} \; changegroup.2=hg update changegroup.3=chgrp -Rf djangoproject . || true changegroup.4=chmod -Rf g+w,o-rwx . || true changegroup.5=find . -type d -exec chmod -f g+xs {} \; changegroup.6=touch django.wsgi # Reloads the app 

这将清除Python字节码,更新工作副本,修复所有的权限,并在开发人员进入部署时重新启动守护程序,以便djangoproject组中的任何人都可以将它推入,而不仅仅是添加文件的最后一个。 不用说,小心你在djangoproject组中的人。


zeekay设置STATIC_URLSTATIC_ROOTSTATICFILES_DIRSSTATICFILES_FINDERS并在其设置中使用"django.contrib.staticfiles""django.core.context_processors.static" 。 我没有这些,因为我的代码可以追溯到Django 1.1,不使用{{ STATIC_ROOT }}

希望这可以帮助。