2019独角兽企业重金招聘Python工程师标准>>>
准备工作
首先,将 settings.py 内的 DEBUG 和 TEMPLATE_DEBUG 项设为 False。
然后,在 templates 目录下实现 404 和 500 模板。
设置错误警告
引发代码异常时将给 ADMINS 内的邮件地址发送错误报告,启用此功能需确保 django 的邮件发送功能正常:
ADMINS = ( ( ' John Lennon ' , ' [email protected] ' ), ( ' Paul McCartney ' , ' [email protected] ' ), )
当用户访问一个非空链接却导致了错误 404 的发生和连接中断的情况时,可以选择给 MANAGERS 发送错误报告。此行为依赖于 CommonMiddleware 的启用以及 SEND_BROKEN_LINK_EMAILS 值为 True。MANAGERS 的语法与 ADMINS 相同。
设置多个配置文件
django 会通过 DJANGO_SETTINGS_MODULE 环境变量来定位配置文件,其内容可以通过“os.environ['DJANGO_SETTINGS_MODULE']”来查看。默认情况下,其值被设为“mysite.settings”。
要为开发和生产环境设置不同的配置文件,如果使用两个不同的文件,可以以一个为基准,另一个来导入,并覆盖存在差异的项:
# settings.py DEBUG = True TEMPLATE_DEBUG = DEBUG DATABASE_ENGINE = ' postgresql_psycopg2 ' DATABASE_NAME = ' devdb ' DATABASE_USER = '' DATABASE_PASSWORD = '' DATABASE_PORT = '' # ... # settings_production.py from settings import * DEBUG = TEMPLATE_DEBUG = False DATABASE_NAME = ' production ' DATABASE_USER = ' app ' DATABASE_PASSWORD = ' letmein '
如果使用一个文件,则需在文件内进行环境判断,比如通过主机名:
# settings.py import socket if socket.gethostname() == ' my-laptop ' : DEBUG = TEMPLATE_DEBUG = True else : DEBUG = TEMPLATE_DEBUG = False # ...
注意:因为环境变量是进程范围的,所以当你在同一个进程中运行多个站点时(比如 mod_wsgi),上面的这种配置不会起作用。这时你需要使用 mod_wsgi 的 daemon 模式,或者在 wsgi.py 文件中通过“os.environ.['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'”这种形式覆盖。
WSGI
最早 Python 实现 web server app 的方式是 CGI,不过因为其会为每一个请求创建一个解释器并且这个解释器只处理这一个请求,而造成了很大的计算压力。因此一个显而易见的解决方案——使用一个内存常驻的 Python 程序来处理全部请求,开始不断被实现。
在这个过程中有两种方式成为主流,一是设计整合进 web server 的 API,比如 mod-python,mod 是 module 的缩写;另一种方式是独立于 web server 的外部进程,比如 FastCGI。
这两种方式都已经被证明为有效的。其中 server API 部署起来更简单,也被 django 推荐给第一次学部署的人使用;而外部进程则避免了前者可能带来的 app 与 server 之间性能影响,以及需要编写针对特定 server 的代码等问题。
于是,(主要)针对这两种不同实现而设计的 web server 与 web framework layer(app) 间的通用接口标准被创造出来,就是 Web Server Gateway Interface(WSGI) standard。注意 WSGI 并不是任何的 server、API 甚至不包含代码实现,它是一种对 API 的定义。
WSGI 应用程序接口的实现是一个可调用对象。他总是接受两个参数:一个由服务器生成的环境变量字典,这个字典里的数据来自于客户端的请求,以及另一个服务器提供的回调函数。这个回调函数接受 HTTP 状态码 和 HTTP 头 来初始化一个响应头。WSGI 应用程序则负责返回页面的响应负载。该负载应当是一个以可迭代对象形式封装的字符串类型,比如简单点的像列表,或者使用 yield 关键字也可以。这个响应负载与初始化完成的响应头再由 WSGI server 组合到一起,并返回给客户端。SAE 教程里提供了一个 Hello world 的例子:
def app(environ, start_response): status = ' 200 OK ' response_headers = [( ' Content-type ' , ' text/plain ' )] start_response(status, response_headers) return [ ' Hello, world! ' ]
注意上例中的变量和参数格式,如 response_headers 必须是一个元组对(header_name, header_value)组成的列表。
Python 标准库里也有一个名为 wsgiref 的简单 wsgi server,可以用于测试:
>>> from wsgiref.simple_server import make_server,demo_app >>> httpd = make_server( '' , 8000 ,demo_app) >>> httpd.serve_forever() 127.0 . 0.1 - - [ 13 / Apr / 2014 15 : 55 :0 8 ] " GET / HTTP/1.1 " 200 4266 127.0 . 0.1 - - [ 13 / Apr / 2014 15 : 55 :0 8 ] " GET /favicon.ico HTTP/1.1 " 200 4206
在 django 中,这个 WSGI app 的配置就保存在项目文件夹下的 wsgi.py 文件中,以 application 命名,是一个模块级的变量。
更详细的内容,可以参考下面一个教程:http://webpython.codepoint.net/wsgi_tutorial
Apache + mod_wsgi
前面提到的 mod_python 现在已经被弃用了,兼容 WSGI 的 mod_wsgi 是现行的标准。
基本配置
在安装并激活 mod_wsgi 后,需要编辑 Apache 的 httpd.conf 文件,并添加下面的内容。如果是 2.4 以后的版本,把下面的 Require all granted 换成 Allow from all:
WSGIScriptAlias / / path / to / mysite.com / mysite / wsgi.py WSGIPythonPath / path / to / mysite.com < Directory / path / to / mysite.com / mysite > < Files wsgi.py > Order deny,allow Require all granted Files > Directory >
第一行 WSGIScriptAlias 后面有两个参数。前面的“/”是你想要启用 app 服务的 URL 路径,单斜杠代表网站的根目录;后面的路径指向系统里的“WSGI 文件”,通常位于项目包内(例子中的 mysite)。这一行的作用是告诉 Apache 对该 URL 开头的所有请求应用那个“WSGI 文件”内指定的 application。
第二行的 WSGIPythonPath 的作用是确保你的项目包在 python 的导入路径之中。换句话说,就是保证“import mysite”这条语句可以执行。
后面的
使用 virtualenv
virtualenv 是一个 Python 虚拟环境管理工具,它可以为 django 创建一套独立的运行环境,以避免与其他程序之间可能因版本造成的兼容性问题。可以参考这篇文章:以正确的方式开始一个 Django 1.6 项目
当你使用了 virtualenv 的时候,你得把 virtualenv 的 site-packages 路径添加到 Python 路径中去。具体的作法为:把这条路径添加到上面提到的 WSGIPythonPath 中,与已有的内容之间用“:”隔开(windows 环境下用 ;)。像这样:
WSGIPythonPath / path / to / mysite.com: / path / to / your / venv / lib / python2.X / site - packages
注意:如果路径中任何一处有空格,一定要把整个参数引用起来。
使用 mod_wsgi 的 daemon mode
“daemon mode”是运行 mod_wsgi 的推荐模式(非 windows 平台上)。要创建必须的 daemon 进程组并运行 django 实例,就得添加适当的 WSGIDeamonProcess 和 WSGIProcessGroup 命令。另一项需要对上面的配置加以修改的地方是:你不能再用 WSGIPythonPath 这个变量了,而是使用 WSGIDaemonProcess 的 python-path 选项,例如:
WSGIDaemonProcess example.com python - path =/ path / to / mysite.com: / path / to / venv / lib / python2. 7 / site - packages WSGIProcessGroup example.com
文件服务
django 本身并不提供文件服务;这个工作应当由 web server 来做。
另外,我们建议使用一个单独的 server 来做这项工作,与运行 django 的独立。比如:
- lighttpd
- Nginx
- TUX
- Apache 的简化版
- Cherokee
如果不得不把媒体文件服务放在同一个 server 上,你可以为 Apache 设置一些 url 来处理静态文件,其余的则通过 mod_wsgi 接口来交给 django 处理。
下例把 django 配置到了网站根目录,但明确设定以静态文件的方式提供 robots.txt、favicon.ico、CSS 文件和位于“/static/”与“/media/”URL 下的全部文件。所有其他的路径交由 django 处理:
Alias / robots.txt / path / to / mysite.com / static / robots.txt Alias / favicon.ico / path / to / mysite.com / static / favicon.ico AliasMatch ^/ ([ ^/ ] * .css) / path / to / mysite.com / static / styles / $ 1 Alias / media / / path / to / mysite.com / media / Alias / static / / path / to / mysite.com / static / < Directory / path / to / mysite.com / static > Order deny,allow Require all granted Directory > < Directory / path / to / mysite.com / media > Order deny,allow Require all granted Directory > WSGIScriptAlias / / path / to / mysite.com / mysite / wsgi.py < Directory / path / to / mysite.com / mysite > < Files wsgi.py > Order allow,deny Require all granted Files > Directory >
同样,如果使用 Apache 2.4 以后的版本,把上面的 Require all granted 换成 Allow from all。
admin 文件服务
当 INSTALLED_APPS 中包含 django.contrib.staticfiles 的时候,django 开发服务器会自动为 admin 和其他 app 的静态文件提供服务。但当你使用其他服务器的时候,情况就不是这样了。你得自己为 Apache 或其他服务器,配置对 admin 文件的服务。
admin 文件位于 django 发布包的 django/contrib/admin/static/admin 位置
我们强烈建议使用 django.contrib.staticfiles 来处理 admin 文件(伴随上面提到的 web server;这意味着,使用 collectstatic 管理命令来把静态文件收集到 STATIC_ROOT,然后配置 web server,使其在 STATIC_URL 上为 STATIC_ROOT 提供服务),不过这里有三种另外的方法:
- 创建一个从文档根目录指向 admin 静态文件的软连接(这可能需要在你的 Apache 配置文件中添加 FollowSymLinks)
- 使用 Alias,像上面展示的那样,把适当的 URL(比如 STATIC_URL + admin/)和 admin 文件的实际位置连接起来
- 把 admin 文件拷贝到 Apache 文档根目录
uWSGI
这里没有提到 web server 是因为 uWSGI 是一个独立的外部进程,类似于 FastCGI。因此可以任意搭配 web server 使用。现在似乎流行着一种选择是 Nginx + uWSGI,或 Nginx + Apache + uWSGI,因为 Nginx 有很好的高并发处理能力,而且相对省资源。针对这种搭配,uWSGI 提供了一个 tutorial:https://uwsgi.readthedocs.org/en/latest/tutorials/Django_and_nginx.html 下文仅针对 django 与 uwsgi 之间的整合进行阐述。
安装
可以简单使用 pip 来安装:
# Install current stable version. $ sudo pip install uwsgi # Or install LTS (long term support). $ sudo pip install http: // projects.unbit.it / downloads / uwsgi - lts.tar.gz
uWSGI 模型
uWSGI 工作在一种“客户端-服务器”模式下。web server 与 django-uwsgi“worker”进程交互以提供动态服务。
配置和启用 uWSGI server
uWSGI 支持多种进程配置方式。下面展示一份启动 uWSGI server 的示例命令:
uwsgi -- chdir =/ path / to / your / project -- module = mysite.wsgi:application -- env DJANGO_SETTINGS_MODULE = mysite.settings -- master -- pidfile =/ tmp / project - master.pid -- socket = 127.0 . 0.1 : 49152 # can also be a file -- processes = 5 # number of worker processes -- uid = 1000 -- gid = 2000 # if root, uwsgi can drop privileges -- harakiri = 20 # respawn processes taking more than 20 seconds -- max - requests = 5000 # respawn processes after serving 5000 requests -- vacuum # clear environment on exit -- home =/ path / to / virtual / env # optional path to a virtualenv -- daemonize =/ var / log / uwsgi / yourproject.log # background the process
上例假设你有一个顶层的 mysite 项目包,并且其 mysite/wsgi.py 模块内有一个 WSGI application 对象。这种布局是你在使用 startproject 命令时默认生成的。
其中针对 django 的选项为:
- chdir : 指向目录的路径,需要包含在 python 的 import 路径内。即,包含有 mysite 包的那个路径
- module : 要使用的 WSGI 模块,比如 mysite/wsgi.py 里面那个
- env : 可能需要至少包含 DJANGO_SETTINGS_MODULE
- home : 可选的,指向项目的 virtualenv 的路径
ini 配置文件示例:
[uwsgi] chdir =/ path / to / your / project module = mysite.wsgi:application master = True pidfile =/ tmp / project - master.pid vacuum = True max - requests = 5000 daemonize =/ var / log / uwsgi / yourproject.log
ini 配置文件使用方法示例:
uwsgi -- ini uwsgi.ini