提交 4a590044 编写于 作者: W wizardforcel

8.29

上级 da39a954
# Django 的设置 #
Django 的设置文件包含你安装的Django 的所有配置。这页文档解释设置是如何工作以及有哪些设置。
## 基础 ##
设置文件只是一个Python 模块,带有模块级别的变量。
下面是一些示例设置:
```
ALLOWED_HOSTS = ['www.example.com']
DEBUG = False
DEFAULT_FROM_EMAIL = 'webmaster@example.com'
```
> 注
>
> 如果你设置`DEBUG` 为`False`,那么你应该正确设置`ALLOWED_HOSTS` 的值。
因为设置文件是一个Python 模块,所以适用以下情况:
+ 不允许出现Python 语法错误。
+ 它可以使用普通的Python 语法动态地设置。例如:
```
MY_SETTING = [str(i) for i in range(30)]
```
+ 它可以从其它设置文件导入值。
## 指定设置文件 ##
`DJANGO_SETTINGS_MODULE`
当你使用Django 时,你必须告诉它你正在使用哪个设置。这可以使用环境变量`DJANGO_SETTINGS_MODULE` 来实现。
`DJANGO_SETTINGS_MODULE` 的值应该使用Python 路径的语法,例如`mysite.settings`。注意,设置模块应该在Python 的导入查找路径 中。
### django-admin 工具 ###
当使用`django-admin` 时, 你可以设置只设置环境变量一次,或者每次运行该工具时显式传递设置模块。
例如(Unix Bash shell):
```
export DJANGO_SETTINGS_MODULE=mysite.settings
django-admin runserver
```
例如(Windows shell):
```
set DJANGO_SETTINGS_MODULE=mysite.settings
django-admin runserver
```
使用--settings 命令行参数可以手工指定设置:
```
django-admin runserver --settings=mysite.settings
```
### 在服务器上(mod_wsgi) ###
在线上服务器环境中,你需要告诉WSGI 的application 使用哪个设置文件。可以使用os.environ 实现:
```
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
```
阅读[Django mod_wsgi 文档](http://python.usyiyi.cn/django/howto/deployment/wsgi/modwsgi.html) 以获得关于Django WSGI application 的更多和其它常见信息。
## 默认的设置 ##
Django 的设置文件不需要定义所有的设置。每个设置都有一个合理的默认值。这些默认值位于`django/conf/global_settings.py` 模块中。
下面是Django 用来编译设置的算法:
+`global_settings.py` 中加载设置。
+ 从指定的设置文件中加载设置,如有必要则覆盖全局的设置。
注意,设置文件不 应该从global_settings 中导入,因为这是多余的。
### 查看改变的设置 ###
有一个简单的方法可以查看哪些设置与默认的设置不一样了。python `manage.py` `diffsettings` 命令显示当前的设置文件和Django 默认设置之间的差异。
获取更多信息,查看`diffsettings` 的文档。
## 在Python 代码中使用设置 ##
在Django 应用中,可以通过导入`django.conf.settings` 对象来使用设置。例如:
```
from django.conf import settings
if settings.DEBUG:
# Do something
```
注意,`django.conf.settings` 不是一个模块 —— 它是一个对象。所以不可以导入每个单独的设置:
```
from django.conf.settings import DEBUG # This won't work.
```
还要注意,你的代码不应该 从`global_settings` 或你自己的设置文件中导入。`django.conf.settings` 抽象出默认设置和站点特定设置的概念;它表示一个单一的接口。它还可以将代码从你的设置所在的位置解耦出来。
## 运行时改变设置 ##
请不要在应用运行时改变设置。例如,不要在视图中这样做:
```
from django.conf import settings
settings.DEBUG = True # Don't do this!
```
给设置赋值的唯一地方是在设置文件中。
## 安全 ##
因为设置文件包含敏感的信息,例如数据库密码,你应该尽一切可能来限制对它的访问。例如,修改它的文件权限使得只有你和Web 服务器使用者可以读取它。这在共享主机的环境中特别重要。
## 可用的设置 ##
完整的可用设置清单,请参见[设置参考](http://python.usyiyi.cn/django/ref/settings.html)
## 创建你自己的设置 ##
没有什么可以阻止你为自己的Django 应用创建自己的设置。只需要遵循下面的一些惯例:
+ 设置名称全部是大写
+ 不要使用一个已经存在的设置
对于序列类型的设置,Django 自己使用元组而不是列表,但这只是一个习惯。
## 不用DJANGO_SETTINGS_MODULE 设置 ##
有些情况下,你可能想绕开`DJANGO_SETTINGS_MODULE` 环境变量。例如,如果你正在使用自己的模板系统,而你不想建立指向设置模块的环境变量。
这些情况下,你可以手工配置Django 的设置。实现这点可以通过调用:
`django.conf.settings.configure(default_settings, **settings)`
例如:
```
from django.conf import settings
settings.configure(DEBUG=True)
```
可以传递`configure()` 给任意多的关键字参数,每个关键字参数表示一个设置及其值。每个参数的名称应该都是大写,与上面讲到的设置名称相同。如果某个设置没有传递给`configure()` 而且在后面需要使用到它,Django 将使用其默认设置的值。
当你在一个更大的应用中使用到Django 框架的一部分,有必要以这种方式配置Django —— 而且实际上推荐这么做。
所以,当通过`settings.configure()` 配置时,Django 不会对进程的环境变量做任何修改(参见`TIME_ZONE` 文档以了解为什么会发生)。在这些情况下,它假设你已经完全控制你的环境变量。
## 自定义默认的设置 ##
如果你想让默认值来自其它地方而不是`django.conf.global_settings`,你可以传递一个提供默认设置的模块或类作为`default_settings` 参数(或第一个位置参数)给`configure()` 调用。
在下面的示例中,默认的设置来自`myapp_defaults`, 并且设置`DEBUG``True`,而不论它在`myapp_defaults` 中的值是什么:
```
from django.conf import settings
from myapp import myapp_defaults
settings.configure(default_settings=myapp_defaults, DEBUG=True)
```
下面的示例和上面一样,只是使用`myapp_defaults` 作为一个位置参数:
```
settings.configure(myapp_defaults, DEBUG=True)
```
正常情况下,你不需要用这种方式覆盖默认值。Django 的默认值以及足够好使,你可以安全地使用它们。注意,如果你传递一个新的默认模块,你将完全取代 Django 的默认值,所以你必须指定每个可能用到的设置的值。完整的设置清单,参见`django.conf.settings.global_settings`
### configure() 和DJANGO_SETTINGS_MODULE 两者必居其一 ###
如果你没有设置`DJANGO_SETTINGS_MODULE` 环境变量,你 必须 在使用到读取设置的任何代码之前调用`configure()`
如果你没有设置`DJANGO_SETTINGS_MODULE` 且没有调用 `configure()`,在首次访问设置时Django 将引发一个`ImportError` 异常。
如果你设置了`DJANGO_SETTINGS_MODULE`,并访问了一下设置,然后 调用`configure()`,Django 将引发一个`RuntimeError` 表示该设置已经有配置。有个属性正好可以用于这个情况:
例如:
```
from django.conf import settings
if not settings.configured:
settings.configure(myapp_defaults, DEBUG=True)
```
另外,多次调用`configure()`或者在设置已经访问过之后调用 `configure()` 都是错误的。
归结为一点:只使用`configure()``DJANGO_SETTINGS_MODULE` 中的一个。不可以两个都用和都不用。
> 另见
>
> [设置参考](http://python.usyiyi.cn/django/ref/settings.html)
> 包含完整的核心设置和contrib 应用设置的列表。
‍
> 译者:[Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html),原文:[Overview](https://docs.djangoproject.com/en/1.8/topics/settings/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 协议发布,转载请保留作者署名和文章出处。
>
> [Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html)人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。
# 编写自定义的django-admin命令 #
应用可以通过`manage.py`注册它们自己的动作。例如,你可能想为你正在发布的Django应用添加一个`manage.py`动作。在本页文档中,我们将为教程中的 `polls`应用构建一个自定义的 `closepoll`命令。
要做到这点,只需向该应用添加一个`management/commands`目录。Django将为该目录中名字没有以下划线开始的每个Python模块注册一个`manage.py`命令。例如:
```
polls/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
_private.py
closepoll.py
tests.py
views.py
```
在Python 2上,请确保`management``management/commands`两个目录都包含`__init__.py` 文件,否则将检测不到你的命令。
在这个例子中,`closepoll`命令对任何项目都可使用,只要它们在`INSTALLED_APPS`里包含`polls`应用。
`_private.py`将不可以作为一个管理命令使用。
`closepoll.py`模块只有一个要求 – 它必须定义一个`Command`类并扩展自`BaseCommand`或其 子类。
> 独立的脚本
>
> 自定义的管理命令主要用于运行独立的脚本或者UNIX crontab和Windows周期任务控制面板周期性执行的脚本。
要实现这个命令,需将`polls/management/commands/closepoll.py`编辑成这样:
```
from django.core.management.base import BaseCommand, CommandError
from polls.models import Poll
class Command(BaseCommand):
help = 'Closes the specified poll for voting'
def add_arguments(self, parser):
parser.add_argument('poll_id', nargs='+', type=int)
def handle(self, *args, **options):
for poll_id in options['poll_id']:
try:
poll = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise CommandError('Poll "%s" does not exist' % poll_id)
poll.opened = False
poll.save()
self.stdout.write('Successfully closed poll "%s"' % poll_id)
```
```
Changed in Django 1.8:
在Django 1.8之前,管理命令基于optparse模块,位置参数传递给*args,可选参数传递给**options。现在,管理命令使用argparse解析参数,默认所有的参数都传递给**options,除非你命名你的位置参数为args(兼容模式)。对于新的命令,鼓励你仅仅使用**options。
```
> 注
>
> 当你使用管理命令并希望提供控制台输出时,你应该写到`self.stdout`和`self.stderr`,而不能直接打印到 `stdout`和`stderr`。通过使用这些代理方法,测试你自定义的命令将变得非常容易。还请注意,你不需要在消息的末尾加上一个换行符,它将被自动添加,除非你指定`ending`参数:
>
```
self.stdout.write("Unterminated line", ending='')
```
>
新的自定义命令可以使用`python manage.py closepoll <poll_id>`调用。
`handle()`接收一个或多个`poll_ids`并为他们中的每个设置 `poll.opened``False`。如果用户访问任何不存在的`polls`,将引发一个`CommandError``poll.opened`属性在教程中并不存在,只是为了这个例子将它添加到`polls.models.Poll`中。
## 接收可选参数 ##
通过接收额外的命令行选项,可以简单地修改`closepoll`来删除一个给定的`poll`而不是关闭它。这些自定义的选项可以像下面这样添加到 `add_arguments()`方法中:
```
class Command(BaseCommand):
def add_arguments(self, parser):
# Positional arguments
parser.add_argument('poll_id', nargs='+', type=int)
# Named (optional) arguments
parser.add_argument('--delete',
action='store_true',
dest='delete',
default=False,
help='Delete poll instead of closing it')
def handle(self, *args, **options):
# ...
if options['delete']:
poll.delete()
# ...
```
```
Changed in Django 1.8:
之前,只支持标准的optparse库,你必须利用optparse.make_option()扩展命令option_list变量。
```
选项(在我们的例子中为`delete`)在`handle`方法的`options`字典参数中可以访问到。更多关于`add_argument`用法的信息,请参考`argparse`的Python 文档。
除了可以添加自定义的命令行选项, 管理命令还可以接收一些默认的选项,例如`--verbosity``--traceback`
## 管理命令和区域设置 ##
默认情况下,`BaseCommand.execute()`方法使转换失效,因为某些与Django一起的命令完成的任务要求一个与项目无关的语言字符串(例如,面向用户的内容渲染和数据库填入)。
```
Changed in Django 1.8:
在之前的版本中,Django强制使用"en-us"区域设置而不是使转换失效。
```
如果,出于某些原因,你的自定义的管理命令需要使用一个固定的区域设置,你需要在你的`handle()`方法中利用I18N支持代码提供的函数手工地启用和停用它:
```
from django.core.management.base import BaseCommand, CommandError
from django.utils import translation
class Command(BaseCommand):
...
can_import_settings = True
def handle(self, *args, **options):
# Activate a fixed locale, e.g. Russian
translation.activate('ru')
# Or you can activate the LANGUAGE_CODE # chosen in the settings:
from django.conf import settings
translation.activate(settings.LANGUAGE_CODE)
# Your command logic here
...
translation.deactivate()
```
另一个需要可能是你的命令只是简单地应该使用设置中设置的区域设置且Django应该保持不让它停用。你可以使用`BaseCommand.leave_locale_alone`选项实现这个功能。
虽然上面描述的场景可以工作,但是考虑到系统管理命令对于运行非统一的区域设置通常必须非常小心,所以你可能需要:
+ 确保运行命令时`USE_I18N`设置永远为`True`(this is a good example of the potential problems stemming from a dynamic runtime environment that Django commands avoid offhand by deactivating translations)。
+ Review the code of your command and the code it calls for behavioral differences when locales are changed and evaluate its impact on predictable behavior of your command.
## 测试 ##
关于如何测试自定义管理命令的信息可以在[测试文档](http://python.usyiyi.cn/django/topics/testing/tools.html#topics-testing-management-commands)中找到。
## Command 对象 ##
`class BaseCommand`
所有管理命令最终继承的基类。
如果你想获得解析命令行参数并在响应中如何调用代码的所有机制,可以使用这个类;如果你不需要改变这个行为,请考虑使用它的子类。
继承`BaseCommand`类要求你实现`handle()`方法。
### 属性 ###
所有的属性都可以在你派生的类中设置,并在`BaseCommand`的子类中使用。
`BaseCommand.args`
一个字符串,列出命令接收的参数,适合用于帮助信息;例如,接收一个应用名称列表的命令可以设置它为‘`<app_label app_label ...>`’。
```
Deprecated since version 1.8:
现在,应该在add_arguments()方法中完成,通过调用parser.add_argument()方法。参见上面的closepoll例子。
```
`BaseCommand.can_import_settings`
一个布尔值,指示该命令是否需要导入Django的设置的能力;如果为`True``execute()`将在继续之前验证这是否可能。默认值为`True`
`BaseCommand.help`
命令的简短描述,当用户运行`python manage.py help <command>`命令时将在帮助信息中打印出来。
`BaseCommand.missing_args_message`
```
New in Django 1.8.
```
如果你的命令定义了必需的位置参数,你可以自定义参数缺失时返回的错误信息。默认是由`argparse`输出的 (“too few arguments”)。
`BaseCommand.option_list`
这是optparse选项列表,将赋值给命令的OptionParser用于解析命令。
```
Deprecated since version 1.8:
现在,你应该覆盖`add_arguments()`方法来添加命令行接收的自定义参数。参见上面的例子。
```
`BaseCommand.output_transaction`
一个布尔值,指示命令是否输出SQL语句;如果为`True`,输出将被自动用`BEGIN;``COMMIT;`封装。默认为`False`
`BaseCommand.requires_system_checks`
```
New in Django 1.7.
```
一个布尔值;如果为`True`,在执行该命令之前将检查整个Django项目是否有潜在的问题。如果`requires_system_checks`缺失,则使用`requires_model_validation`的值。如果后者的值也缺失,则使用默认值(`True`)。同时定义`requires_system_checks``requires_model_validation`将导致错误。
`BaseCommand.requires_model_validation`
```
Deprecated since version 1.7:
被requires_system_checks代替
```
一个布尔值;如果为`True`,将在执行命令之前作安装的模型的验证。默认为`True`。若要验证一个单独应用的模型而不是全部应用的模型,可以调用在`handle()`中调用`validate()`
`BaseCommand.leave_locale_alone`
一个布尔值,指示设置中的区域设置在执行命令过程中是否应该保持而不是强制设成‘en-us’。
默认值为`False`
如果你决定在你自定义的命令中修改该选项的值,请确保你知道你正在做什么。 如果它创建对区域设置敏感的数据库内容,这种内容不应该包含任何转换(比如`django.contrib.auth`权限发生的情况),因为将区域设置变成与实际上默认的‘en-us’ 不同可能导致意外的效果。更进一步的细节参见上面的[管理命令和区域设置](http://python.usyiyi.cn/django/howto/custom-management-commands.html#id1)一节。
`can_import_settings`选项设置为`False`时,该选项不可以也为`False`,因为尝试设置区域设置需要访问`settings`。这种情况将产生一个`CommandError`
## 方法 ##
`BaseCommand`有几个方法可以被覆盖,但是只有`handle()`是必须实现的。
> 在子类中实现构造函数
>
> 如果你在`BaseCommand的`子类中实现`__init__`,你必须调用`BaseCommand`的`__init__`:
>
```
class Command(BaseCommand):
def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs)
# ...
```
>
`BaseCommand.add_arguments(parser)`
```
New in Django 1.8.
```
添加解析器参数的入口,以处理传递给命令的命令行参数。自定义的命令应该覆盖这个方法以添加命令行接收的位置参数和可选参数。当直接继承`BaseCommand`时不需要调用`super()`
`BaseCommand.get_version()`
返回Django的版本,对于所有内建的Django命令应该都是正确的。用户提供的命令可以覆盖这个方法以返回它们自己的版本。
`BaseCommand.execute(*args, **options)`
执行这个命令,如果需要则作系统检查(通过 `requires_system_checks`属性控制)。如果该命令引发一个`CommandError`,它将被截断并打印到标准错误输出。
> 在你的代码中调用管理命令
>
> 不应该在你的代码中直接调用`execute()`来执行一个命令。请使用`call_command`。
`BaseCommand.handle(*args, **options)`
命令的真正逻辑。子类必须实现这个方法。
`BaseCommand.check(app_configs=None, tags=None, display_num_errors=False)`
```
New in Django 1.7.
```
利用系统的检测框架检测全部Django项目的潜在问题。严重的问题将引发`CommandError`;警告会输出到标准错误输出;次要的通知会输出到标准输出。
如果`app_configs``tags`都为`None`,将进行所有的系统检查。`tags`可以是一个要检查的标签列表,比如`compatibility``models`
`BaseCommand.validate(app=None, display_num_errors=False)`
```
Deprecated since version 1.7:
被check命令代替
```
如果`app``None`,那么将检查安装的所有应用的错误。
### BaseCommand 的子类 ###
`class AppCommand`
这个管理命令接收一个或多个安装的应用标签作为参数,并对它们每一个都做一些动作。
子类不用实现`handle()`,但必须实现`handle_app_config()`,它将会为每个应用调用一次。
`AppCommand.handle_app_config(app_config, **options)`
`app_config`完成命令行的动作,其中`app_config``AppConfig`的实例,对应于在命令行上给出的应用标签。
> Changed in Django 1.7:
>
> 以前,AppCommand子类必须实现`handle_app(app, **options)`,其中`app`是一个模型模块。新的API可以不需要模型模块来处理应用。迁移的最快的方法如下:
>
```
def handle_app_config(app_config, **options):
if app_config.models_module is None:
return # Or raise an exception.
app = app_config.models_module
# Copy the implementation of handle_app(app_config, **options) here.
```
>
> 然而,你可以通过直接使用`app_config`的属性来简化实现。
`class LabelCommand`
这个管理命令接收命令行上的一个或多个参数(标签),并对它们每一个都做一些动作。
子类不用实现`handle()`,但必须实现`handle_label()`,它将会为每个标签调用一次。
`LabelCommand.handle_label(label, **options)`
`label`完成命令行的动作,`label`是命令行给出的字符串。
`class NoArgsCommand`
```
Deprecated since version 1.8:
使用BaseCommand代替,它默认也不需要参数。
```
这个命令不接收命令行上的参数。
子类不需要实现`handle()`,但必须实现`handle_noargs()``handle()`本身已经被覆盖以保证不会有参数传递给命令。
`NoArgsCommand.handle_noargs(**options)`
完成这个命令的动作
### Command 的异常 ###
`class CommandError`
异常类,表示执行一个管理命令时出现问题。
如果这个异常是在执行一个来自命令行控制台的管理命令时引发,它将被捕获并转换成一个友好的错误信息到合适的输出流(例如,标准错误输出);因此,引发这个异常(并带有一个合理的错误描述)是首选的方式来指示在执行一个命令时某些东西出现错误。
如果管理命令从代码中通过call_command调用,那么需要时捕获这个异常由你决定。
> 译者:[Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html),原文:[Adding custom commands](https://docs.djangoproject.com/en/1.8/howto/custom-management-commands/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 协议发布,转载请保留作者署名和文章出处。
>
> [Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html)人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。
# 部署 Django #
虽然Django 满满的便捷性让Web 开发人员活得轻松一些,但是如果不能轻松地部署你的网站,这些工具还是没有什么用处。Django 起初,易于部署就是一个主要的目标。有许多优秀的方法可以轻松地来部署Django:
+ [如何使用WSGI 部署](http://python.usyiyi.cn/django/howto/deployment/wsgi/index.html)
+ [部署的检查清单](http://python.usyiyi.cn/django/howto/deployment/checklist.html)
FastCGI 的支持已经废弃并将在Django 1.9 中删除。
+ [如何使用FastCGI、SCGI 和AJP 部署Django](http://python.usyiyi.cn/django/howto/deployment/fastcgi.html)
如果你是部署Django 和/或 Python 的新手,我们建议你先试试 [mod_wsgi](http://python.usyiyi.cn/django/howto/deployment/wsgi/modwsgi.html)。 在大部分情况下,这将是最简单、最迅速和最稳当的部署选择。
> 另见
>
> [Django Book(第二版)的第12 章](http://www.djangobook.com/en/2.0/chapter12.html) 更详细地讨论了部署,尤其是可扩展性。但是请注意,这个版本是基于Django 1.1 版本编写,而且在`mod_python` 废弃并于Django 1.5 中删除之后一直没有更新。
&zwj;
> 译者:[Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html),原文:[Overview](https://docs.djangoproject.com/en/1.8/howto/deployment/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 协议发布,转载请保留作者署名和文章出处。
>
> [Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html)人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。
# 如何使用WSGI 部署 #
Django 首要的部署平台是[WSGI](http://www.wsgi.org/),它是Python Web 服务器和应用的标准。
Django 的`startproject` 管理命名为你设置一个简单的默认WSGI 配置,你可以根据你项目的需要做调整并指定任何与WSGI 兼容的应用服务器使用。
Django 包含以下WSGI 服务器的入门文档:
+ [如何使用Apache 和mod_wsgi 部署Django](http://python.usyiyi.cn/django/howto/deployment/wsgi/modwsgi.html)
+ [从Apache 中利用Django 的用户数据库进行认证](http://python.usyiyi.cn/django/howto/deployment/wsgi/apache-auth.html)
+ [如何使用Gunicorn 部署Django (100%)](http://python.usyiyi.cn/django/howto/deployment/wsgi/gunicorn.html)
+ [如何使用uWSGI 部署Django (100%)](http://python.usyiyi.cn/django/howto/deployment/wsgi/uwsgi.html)
## application 对象 ##
使用WSGI 部署的核心概览是`application` 可调用对象,应用服务器使用它来与你的代码进行交换。在Python 模块中,它通常一个名为`application` 的对象提供给服务器使用。
`startproject` 命令创建一个`<project_name>/wsgi.py` 文件,它就包含这样一个`application` 可调用对象。
它既可用于Django 的开发服务器,也可以用于线上WSGI 的部署。
WSGI 服务器从它们的配置中获得`application` 可调用对象的路径。Django 内建的服务器,叫做`runserver``runfcgi` 命令,是从`WSGI_APPLICATION` 设置中读取它。默认情况下,它设置为`<project_name>.wsgi.application`,指向`<project_name>/wsgi.py` 中的`application` 可调用对象。
## 配置settings 模块 ##
当WSGI 服务器加载你的应用时,Django 需要导入settings 模块 —— 这里是你的全部应用定义的地方。
Django 使用`DJANGO_SETTINGS_MODULE` 环境变量来定位settings 模块。它包含settings 模块的路径,以点分法表示。对于开发环境和线上环境,你可以使用不同的值;这完全取决于你如何组织你的settings。
如果这个变量没有设置,默认的`wsgi.py` 设置为`mysite.settings`,其中`mysite` 为你的项目的名称。这是`runserver` 如何找到默认的`settings` 文件的机制。
> 注
>
> 因为环境变量是进程范围的,当你在同一个进程中运行多个Django 站点时,它将不能工作。使用`mod_wsgi` 就是这个情况。
>
> 为了避免这个问题,可以使用mod_wsgi 的守护进程模式,让每个站点位于它自己的守护进程中,或者在`wsgi.py`中通过强制使用`os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings"` 来覆盖这个值。
## 运用WSGI 中间件 ##
你可以简单地封装application 对象来运用 [WSGI 中间件](https://www.python.org/dev/peps/pep-3333/#middleware-components-that-play-both-sides)。 例如,你可以在`wsgi.py` 的底下添加以下这些行:
```
from helloworld.wsgi import HelloWorldApplication
application = HelloWorldApplication(application)
```
如果你结合使用 Django 的application 与另外一个WSGI application 框架,你还可以替换Django WSGI 的application 为一个自定义的WSGI application。
> 注
>
> 某些第三方的WSGI 中间件在处理完一个请求后不调用响应对象上的`close` —— most notably Sentry’s error reporting middleware up to version 2.0.7。这些情况下,不会发送`request_finished` 信号。这可能导致数据库和memcache 服务的空闲连接。
&zwj;
> 译者:[Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html),原文:[WSGI servers](https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 协议发布,转载请保留作者署名和文章出处。
>
> [Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html)人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。
# 部署静态文件 #
> 另见
>
> `django.contrib.staticfiles` 的用法简介,请参见[管理静态文件(CSS、images)](http://python.usyiyi.cn/django/howto/static-files/index.html)。
在线上环境部署静态文件
放置静态文件到线上环境的基本步骤很简单:当静态文件改变时,运行`collectstatic` 命令,然后安排将收集好的静态文件的目录(`STATIC_ROOT`) 搬到静态文件服务器上。取决于`STATICFILES_STORAGE`,这些文件可能需要手工移动到一个新的位置或者`Storage` 类的`post_process` 方法可以帮你。
当然,与所有的部署任务一样,魔鬼隐藏在细节中。每个线上环境的建立都会有所不同,所以你需要调整基本的纲要以适应你的需求。下面是一些常见的方法,可能有所帮助。
### 网站和静态文件位于同一台服务器上 ###
如果你的静态文件和网站位于同一台服务器,流程可能像是这样:
+ 将你的代码推送到部署的服务器上。
+ 在这台服务器上,运行`collectstatic` 来收集所有的静态文件到`STATIC_ROOT`
+ 配置Web 服务器来托管URL` STATIC_URL`下的`STATIC_ROOT`。 例如,这是[如何使用Apache 和mod_wsgi 来完成它](http://python.usyiyi.cn/django/howto/deployment/wsgi/modwsgi.html#serving-files)
你可能想自动化这个过程,特别是如果你有多台Web 服务器。有许多种方法来完成这个自动化,但是许多Django 开发人员喜欢 [Fabric](http://fabfile.org/)
在一下的小节中,我们将演示一些示例的Fabric 脚本来自动化不同选择的文件部署。Fabric 脚本的语法相当简单,但这里不会讲述;参见[Fabric 的文档](http://docs.fabfile.org/) 以获得其语法的完整解释。
所以,一个部署静态文件来多台Web 服务器上的Fabric 脚本大概会是:
```
from fabric.api import *
# Hosts to deploy onto
env.hosts = ['www1.example.com', 'www2.example.com']
# Where your project code lives on the server
env.project_root = '/home/www/myproject'
def deploy_static():
with cd(env.project_root):
run('./manage.py collectstatic -v0 --noinput')
```
### 静态文件位于一台专门的服务器上 ##
大部分大型的Django 站点都使用一台单独的Web 服务器来存放静态文件 —— 例如一台不运行Django 的服务器。这种服务器通常运行一种不同类型的服务器 —— 更快但是功能很少。一些常见的选择有:
+ [Nginx](http://wiki.nginx.org/Main)
+ 裁剪版的[Apache](http://httpd.apache.org/)
配置这些服务器在这篇文档范围之外;查看每种服务器各自的文档以获得说明。
既然你的静态文件服务器不会允许Django,你将需要修改的部署策略,大概会是这样:
+ 当静态文件改变时,在本地运行`collectstatic`
+ 将你本地的`STATIC_ROOT` 推送到静态文件服务器相应的目录中。在这一步,常见的选择[rsync](https://rsync.samba.org/) ,因为它只传输静态文件改变的部分。
下面是Fabric 脚本大概的样子:
```
from fabric.api import *
from fabric.contrib import project
# Where the static files get collected locally. Your STATIC_ROOT setting.
env.local_static_root = '/tmp/static'
# Where the static files should go remotely
env.remote_static_root = '/home/www/static.example.com'
@roles('static')
def deploy_static():
local('./manage.py collectstatic')
project.rsync_project(
remote_dir = env.remote_static_root,
local_dir = env.local_static_root,
delete = True
)
```
### 静态文件位于一个云服务或CDN 上 ###
两位一个常见的策略是放置静态文档到一个云存储提供商比如亚马逊的S3 和/或一个CDN(Content Delivery Network)上。这让你可以忽略保存静态文件的问题,并且通常可以加快网页的加载(特别是使用CDN 的时候)。
当使用这些服务时,除了不是使用rsync 传输你的静态文件到服务器上而是到存储提供商或CDN 上之外,基本的工作流程和上面的差不多。
有许多方式可以实现它,但是如果提供商具有API,那么自定义的文件存储后端 将使得这个过程相当简单。如果你已经写好或者正在使用第三方的自定义存储后端,你可以通过设置`STATICFILES_STORAGE` 来告诉`collectstatic` 来使用它。
例如,如果你已经在`myproject.storage.S3Storage` 中写好一个S3 存储的后端,你可以这样使用它:
```
STATICFILES_STORAGE = 'myproject.storage.S3Storage'
```
一旦完成这个,你所要做的就是运行`collectstatic`,然后你的静态文件将被你的存储后端推送到S3 上。如果以后你需要切换到一个不同的存储提供商,你只需简单地修改你的`STATICFILES_STORAGE` 设置。
关于如何编写这些后端的细节,请参见[编写一个自定义的存储系统](http://python.usyiyi.cn/django/howto/custom-file-storage.html)。有第三方的应用提供存储后端,它们支持许多常见的文件存储API。一个不错的入口是[djangopackages.com 的概览](https://www.djangopackages.com/grids/g/storage-backends/)
## 了解更多 ##
关于`django.contrib.staticfiles` 中包含的设置、命令、模板标签和其它细节,参见[staticfiles 参考](http://python.usyiyi.cn/django/ref/contrib/staticfiles.html)
> 译者:[Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html),原文:[Deploying static files](https://docs.djangoproject.com/en/1.8/howto/static-files/deployment/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 协议发布,转载请保留作者署名和文章出处。
>
> [Django 文档协作翻译小组](http://python.usyiyi.cn/django/index.html)人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册