Django官方並沒有提供標准的項目結構,於是網上眾說紛紜,百花齊放,一千個讀者有一千個哈姆雷特。那我們該怎么設計項目結構呢?在回答這個問題之前,先了解一下Django原生的目錄和文件都是干嘛的。
project
在使用django-admin startproject
命令后就會創建這樣的目錄文件,如下:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
根目錄mysite/
根目錄的mysite/,僅僅是個目錄而已,Django不會拿它做什么,它的名字可以隨意修改。
帶短橫線的根目錄
分享一個踩坑經驗,有時候我們想把項目名命名為帶短橫線的,如 hello-world,通過命令直接創建會報錯:
...\> django-admin startproject hello-world
CommandError: 'hello-world' is not a valid project name. Please make sure the name is a valid identifier.
startproject
不支持直接創建帶短橫線的項目名。
方法1 加參數
其實!它是支持的,只是我們漏了一個參數。startproject
的完整格式為django-admin startproject name [directory]
,可以在后面追加一個目錄參數:
...\> django-admin startproject helloworld hello-world
就可以了。根目錄是hello-world
,里面的project是helloworld
。
方法2 改名字
先用helloworld創建,然后再修改,可以①在資源管理器中直接修改文件夾,②也可以在 PyCharm 中修改:

選擇Rename directory:

注意去掉勾選Search,不修改其他位置:

只修改這個根目錄的名字即可。
manage.py
Django的命令行工具,使用頻繁,格式為:
python manage.py <command> [options]
內部mysite.py/
Django項目實際使用到的Python包,存放項目配置、URL路由等。
mysite/__init__.py
表明這個目錄是Python包。
mysite/settings.py
Django項目配置。
mysite/urls.py
URL路由。
mysite/asgi.py
兼容ASGI Web服務器的入口。
mysite/wsgi.py
兼容WSGI Web服務器的入口。
ASGI和WSGI,都是一種Python的Web服務網關接口協議,是在CGI通用網關接口,Common Gateway Interface)的標准上構建的。
app
app是Django項目的應用,一個project可以包含多個app。在使用django-admin startapp
命令后就會創建這樣的目錄文件,如下:
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
polls/
app的Python包,可以放在任意路徑。修改存放路徑,相關配置中的路徑也需要修改。
admin.py
存放Django自帶后台管理的models。
apps.py
app配置信息,例如:
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = 'polls'
存放路徑不同,name的值也不同。
migrations/
Django數據遷移生成的遷移記錄文件。
models.py
存放app的models。
tests.py
單元測試。
views.py
視圖函數(類)。
urls.py
app的路由配置,需要手動添加,可通過include()
函數導入到mysite/urls.py
中,例如:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('polls/', include('polls.urls')),
]
polls/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
]
訪問xxx/polls/
就會路由到views.index
。
工程化項目參考
雖說是百家爭鳴,但也有公認的工程化實踐。我找了GitHub上star最多的叫做Django Edge的project skeleton,它的設計如下:
Top-directory
├── docs
├── logs
├── README.md
├── requirements
│ ├── base.txt
│ ├── development.txt
│ └── production.txt
├── requirements.txt
└── src
├── Your project name
│ ├── __init__.py
│ ├── logger.py
│ ├── settings
│ │ ├── base.py
│ │ ├── development.py
│ │ ├── local.sample.env
│ │ └── production.py
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
├── accounts
│ ├── admin.py
│ ├── forms.py
│ ├── migrations
│ ├── models.py
│ ├── templates
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── media
├── profiles
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations
│ ├── models.py
│ ├── signals.py
│ ├── templates
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── static
│ ├── bootstrap
│ │ ├── css
│ │ ├── fonts
│ │ └── js
│ └── site
│ ├── css
│ ├── ico
│ ├── img
│ └── js
└── templates
非常的像那么回事。我又搜了其他實踐的文章,找到了這張圖:

國內的文章也有提到類似這2種項目結構的設計,特點是①app放置在單獨目錄統一管理,②requirements和settings按環境做拆分,等等等。我說說我的觀點,一開始沒有必要就按照這種標准的工程化實踐來寫項目,我更傾向於先憑自己的能力寫一版,再不斷重構和優化的方式。業務不同,能力不同,經驗不同,寫出來的代碼自然也不同。不過在碰到問題時,可以參考借鑒,很可能別人已經提供了解決方案。
我看了一些Django開源項目代碼,很少見到真像這么設計項目結構的,所以不必過分在意。
小結
本文介紹了Django startproject和startapp命令產生的目錄文件的結構和作用。然后給出了工程化項目參考。項目結構沒有標准,只有適用於當前的最佳實踐,可能這就是官方沒有給出標准項目結構的原因吧。
參考資料:
https://docs.djangoproject.com/en/3.1/intro/tutorial01/
https://django-edge.readthedocs.io/en/latest/Architecture/
https://studygyaan.com/django/best-practice-to-structure-django-project-directories-and-files