Django in Action: Project Structure

Django in Action: Project Structure

Why Important ?

一般来说,一旦在开发初期定义好了项目结构,之后大部分人只会按照原有结构修补扩展,而自己又很难有时间去重构。因此一定要在项目初期定义好合适的项目结构。

How ?

自己总结的几个原则:

  1. 文件组织有层次,分门别类放在一起;
  2. 按照使用频率组织,使用频繁的放在触手可及的位置;
  3. ……

A General Python Project Structure

1
2
3
4
5
6
7
8
9
10
11
project_name
|—— LICENSE # 开源协议
|—— MANIFEST.in # 配合 setup.py 使用
|—— README.md # 项目介绍
|—— conf/ # 配置文件,例如 Nginx 的配置
|—— fabfile/ # Fabric 配置,用于部署
|—— others/ # 其它内容,例如需求文档、项目文档
|—— requirements.txt # 项目依赖
|—— setup.py # 打包项目
|—— src/ # 源码目录
|—— .gitignore

/dist/build 可以生成的内容不需要放进源码管理中。

A Django Project Structure

目录结构

这里说的是源码目录部分 src/

1
2
3
4
5
6
7
8
9
10
11
12
13
project_name
|—— project_name (src/)
| |—— app1 # 应用 1
| |—— app2 # 应用 2
| |—— project_name # 项目配置文件
| |—— settings # 项目配置包
| | |—— __init__.py
| | |—— base.py # 基础配置
| | |—— product.py # 生产环境配置
| | |—— develop.py # 开发环境配置
| | |—— ...
| |—— manage.py
|—— ...

这里主要说明怎样拆分 settings.py 文件。

拆分 settings.py

生产环境和开发环境有着不同的配置,例如数据库、域名和缓存。仅仅靠一个 settings.py 很难方便地管理,因此可以将其拆分成三部分,再加上 __init__.py 组成 package 来调用:

  • base.py
  • develop.py
  • product,py

一般将原来的 settings.py 重命名为 base.py,在 product.pydevelop.py 中通过 from base import * 调用,然后重新设置以覆盖掉原有设置。

拆分完成后,还需要更改 manage.pywsgi.py 文件:

原来的 manage.py 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dev_test.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)


if __name__ == '__main__':
main()

注意,os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_test.settings') 这一行设置了 Settings 模块,可以更改为:

1
2
profile = os.environ.get("PROJECT_PROFILE", "develop")
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dev_test.settings.{}'.format(profile))

原来的 wsgi.py 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
"""
WSGI config for dev_test project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dev_test.settings')

application = get_wsgi_application()

同样更改为:

1
2
profile = os.environ.get("PROJECT_PROFILE", "develop")
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dev_test.settings.{}'.format(profile))

这样可以通过设置 PROJECT_PROFILE 环境变量为 developproduct 来加载不同配置。