默认情况下,包含 WSGI 应用、设置模 块和 URL 配置的包名称与项目名称相同。由于我们决定采用打包方法,所以将其命名为

│ ├── index.html

│ └── some_view.html ├── __init__.py

├── admin.py

├── apps.py

├── models.py

├── tests.py

└── views.py __init__.py

6.3 你自己的包索引或索引镜像 163

webxample。这可能会造成一些混淆,所以最好将其重命名为 conf。 我们不去钻研可能的实现细节,只是做几个简单的假设。 我们的应用示例有一些外部依赖,这里包括两个常用的 Django 包:djangorest

framework 和 django-allauth,还有一个非 Django 包:gunicorn。

● djangorestframework和django-allauth在webexample.webexample.

settings 模块中由 INSTALLED_APPS 给出。

● 应用被本地化为 3 种语言(德语、英语和波兰语),但我们不希望将编译过的

gettext 消息保存在仓库中。

● 我们讨厌普通的 CSS 语法,因此我们决定使用更强大的 SCSS 语言,我们可以用

SASS 将其转换为 CSS。

知道了项目的结构之后,我们可以编写 setup.py 脚本,让 setuptools 处理以下

内容。

● 在 webxample/myapp/static/scss 目录下编译 SCSS 文件。

● 在 webexample/locale 目录下将 gettext 消息由.po 格式编译为.mo 格式。 安装需求:

● 为包提供一个入口点的新脚本,这样我们将使用自定义命令,而不是 manage.py

脚本。

我们这里有一些运气成分。Python 绑定了 libsass(SASS 引擎的 C/C++端口),提

供了一些与 setuptools 和 distutils 的集成。只需要很少的配置,它就可以提供自定 义的 setup.py 命令来运行 SASS 编译,如下所示:

      from setuptools import setup

setup(

name='webxample', setup_requires=['libsass >= 0.6.0'], sass_manifests={

              'webxample.myapp': ('static/sass', 'static/css')

          },

)

因此,我们可以输入 python setup.py build_scss 将我们的 SCSS 文件编译成 CSS,而不用手动运行 sass 命令或者在 setup.py 脚本中执行子进程。这还不够。它让 我们的生活更轻松,但我们希望整个分发过程能够完全自动化,只需一步就可以创建新版 本。为了实现这个目标,我们不得不覆写一部分现有的 setuptools 分发命令。

setup.py 文件通过打包来处理一些项目准备步骤,其示例可能如下所示:


164 第6章 部署代码 import os

from setuptools import setup

from setuptools import find_packages

from distutils.cmd import Command

from distutils.command.build import build as _build

      try:

          from django.core.management.commands.compilemessages \

              import Command as CompileCommand

      except ImportError:

# 注意:安装期间 django 可能不可用 CompileCommand = None

# 这个环境是必需的 os.environ.setdefault(

"DJANGO_SETTINGS_MODULE", "webxample.conf.settings" )

class build_messages(Command):

""" 自定义命令,用于在构建 Django 中的 gettext 消息。 """

description = """compile gettext messages""" user_options = []

def initialize_options(self): pass

def finalize_options(self): pass

          def run(self):

              if CompileCommand:

                  CompileCommand().handle(

                      verbosity=2, locales=[], exclude=[]

) else:

raise RuntimeError("could not build translations") class build(_build):

6.3 你自己的包索引或索引镜像 165

""" 覆写了添加额外构建步骤的构建命令。 """

sub_commands = [

('build_messages', None),

('build_sass', None), ] + _build.sub_commands

setup( name='webxample', setup_requires=[

              'libsass >= 0.6.0',

              'django >= 1.9.2',

          ],

install_requires=[

'django >= 1.9.2',

'gunicorn == 19.4.5', 'djangorestframework == 3.3.2', 'django-allauth == 0.24.1',

], packages=find_packages('.'), sass_manifests={

              'webxample.myapp': ('static/sass', 'static/css')

          },

cmdclass={

'build_messages': build_messages, 'build': build,

}, entry_points={

'console_scripts': {

'webxample = webxample.manage:main',

} }

)

利用这样的实现,我们用下面这一个终端命令就可以构建所有资产并为 webxample

项目创建包的源代码发行版,代码如下: