Django 项目结构的最佳做法
今天在这篇文章里,我将带你浏览我为我的Django项目创建的一个通用模板。它遵循了最佳实践,让你能够构建符合工业标准的Django项目。
与其不必费心于你的Django项目结构,还是把时间花在开发酷炫的功能上。
这得到了来自DCI和CF的同学和学生们的许多好评。
提示:请查看我从GitHub上的Django 模板
以下是我们将要讨论的内容。
- 从虚拟环境开始
- 创建Django项目
- 需求
- 配置
- Django应用(或模块)
- Makefile命令快捷方式
一个虚拟环境(Virtual Environment)是一个轻量级的 Python 安装环境,拥有它自己的包目录。
全局安装包通常需要高级权限,如 root
, sudo
等。在这种情况下,setup.py
脚本会具有超级用户权限。如果包里有恶意软件,这将带来严重的安全威胁。
此外,使用命令 pip install --upgrade <package>
会安装并升级该包及其所有依赖项,这可能会影响现有的包,甚至导致其他项目无法正常运行。
最后,全局安装所有包会搞乱包的列表,让跟踪特定项目的依赖变得很难。
创建一个虚拟环境并在其中安装 Django从 Python 3.6 开始,我们可以使用命令来创建虚拟环境。
使用命令 python3 -m venv <文件夹名>
创建一个虚拟环境,可选地,你可以通过 [--prompt <venv名称>]
来自定义提示符。
注意:在 Ubuntu 系统中,我们需要通过 apt
来安装 python3-venv
。这是因为 venv
模块默认情况下不在 Ubuntu 的 Python 安装中。
另一个选择是使用 virtualenv
,可以通过 pip install virtualenv
来全局安装。
现在我们来为我们的 Django 项目创建一个虚拟环境。在 Django_First
文件夹中打开终端,并输入如下命令:
在命令行中输入以下命令:
python -m venv .venv --prompt django-first
在创建虚拟环境后,需要先激活它才能安装任何包。
source .venv/bin/activate
# 激活虚拟环境
然后,安装Django框架。我在这里使用~=
来安装同一主要版本系列的最新版本,例如,这在版本5
系列中适用。
pip install Django ~=5.0.0
注:此命令用于安装兼容5.0.0版本的Django,具体版本范围遵循Python打包标准。
创建一个Django项目要创建Django项目,我们需要使用命令django-admin
以及子命令startproject
。然后指定一些文件夹路径。
django-admin startproject <项目名称> [<配置文件夹>]
比如说,我们想让项目名是 djangofirst
。许多初学者会这样创建。
运行 `django-admin startproject djangofirst`
这就是你按照上述方法做的项目结构图示。
.
├── Django_First
│ └── djangofirst
│ ├── djangofirst
│ │ ├── __init__.py # 初始化文件
│ │ ├── asgi.py # 异步支持文件
│ │ ├── settings.py # 项目设置文件
│ │ ├── urls.py # URL路由配置文件
│ │ └── wsgi.py # HTTP服务器接口文件
│ └── manage.py # 管理脚本
可以看到有很多文件夹,其中一些文件夹还具有相同的名称。在这个例子中,我们为项目创建了一个名为 Django_First
的文件夹,并在其中创建了虚拟环境。然后运行了 Django 的 startproject
命令,结果就有了两个名为 Django_First
的文件夹。
请注:为了指定配置文件夹名称,我们需要确认该文件夹已存在于该目录中。
最佳做法既然我们已经创建了以项目名称命名的文件夹,为了有效地创建Django项目而不自动生成那些嵌套文件夹,我们可以运行该命令。
运行命令:django-admin startproject config .
,这将启动一个新的Django项目并命名为config。
这将是我们的新的架构
.
├── Django_First
│ ├── 配置
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ └── manage.py
注:Django_First
是一个使用 Django 框架的项目,其中 配置
文件夹包含了项目的设置信息,如 settings.py
文件包含了项目的配置设置,urls.py
文件定义了项目的 URL 路由。manage.py
是一个命令行工具,用于执行各种 Django 管理命令。
在这个新结构下,我们的项目初始名称保持不变,配置现在也是config
了。
当需要安装包时,大多数开发者会在 pypi
上搜索并安装他们想要的版本,或者直接运行 pip install <package-name>
。这样就会安装最新版本。其他人只需要一个 requirements.txt
文件。
如果你重视向后兼容性,并且认识到你的项目运行在不同的环境中,那么你就要确保运行你项目的每个人使用正确的版本号。此外,不应在环境中安装不必要的包。
一个复杂的项目需要一个 requirements.txt
文件,这样任何人都可以获取你的项目源码,创建他们自己的虚拟环境,并通过命令 pip install -r requirements.txt
安装所有正确版本的包。
在这里,我们将考虑我们的项目可以运行的不同环境,例如:development
,staging
,production
等。我们不希望像 ipython
这样的开发时常用的包出现在生产环境中,比如。
我们要创建不同的环境,使用各自特定需求的文件和包。
base.txt
: 这文件将包含所有环境中都共用的包dev.txt
: 这文件将包含仅用于开发的包
.
├── Django_First
│ ├── config
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── manage.py
**│ └── requirements
│ ├── base.txt
│ └── dev.txt**
现在我们已经有了这个结构,让我们来瞧瞧针对每个环境可以装的包有哪些。
## 基础.txt
Django~=5.0
django-environ==0.11.2
## 开发.txt
-r 基础.txt
ipython==8.18.1
django-extensions==3.2.3
这里就是…
Django
:主要使用的框架,django-environ
:用来读取环境变量,ipython
:提供强大的交互式 Python 控制台,django_extensions
:在启动 shell 时自动导入 Django 必要的包和模块,
注意:从 dev.txt
安装会从 base.txt
间接安装,这是由于 -r base.txt
这一行。此外,还可以创建如生产环境等其他环境。查看我的视频将 Django Web 应用部署到 Railway,了解我是如何使用生产环境将 Django 项目部署到 Railway 的。
Django 默认自带一个 setting.py
文件,其中包含了 Django 项目的设置。这在非常简单的 Django 项目中是够用的。
就像我们处理上述要求那样,我们也希望确保能够处理各种环境。此外,将所有环境的配置放在一个文件中肯定无法扩展。
这里,我们将创建一个名为 settings/
的文件夹(夹),然后在其中针对不同的环境创建不同的 Python 模块(件)。
.
├── Django_First
│ ├── config
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings # 设置文件,保持原英文名称以确保技术准确性
│ │ │ ├── base.py
│ │ │ └── dev.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── manage.py
│ └── requirements
│ ├── base.txt
│ └── dev.txt
base.py
: 这里包含了所有环境共有的配置信息dev.py
: 这里包含了开发环境的配置信息
base.py
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent.parent
DEFAULT_APP = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
CREATED_APP = [] # 这里可以放自定义应用
THIRD_PARTY_APP = [] # 这里可以放第三方应用
INSTALLED_APPS = [*DEFAULT_APP, *CREATED_APP, *THIRD_PARTY_APP] # 安装的应用程序包括默认应用、自定义应用和第三方应用
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "config.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "config.wsgi.application"
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", # 密码验证器包括用户属性相似性验证器等
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
LANGUAGE_CODE = "en-us" # 设置语言代码
TIME_ZONE = "UTC" # 设置时区为UTC
USE_I18N = True # 启用国际化功能
USE_TZ = True # 启用时区支持
STATIC_URL = "static/"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # 模型默认使用的主键字段类型
dev.py(这是一个开发用的Python脚本文件)
import environ
from .base import *
env = environ.Env(DEBUG=(bool, True))
environ.Env.read_env(str(BASE_DIR / ".env"))
SECRET_KEY = env.str("SECRET_KEY")
DEBUG = env.bool("DEBUG")
ALLOWED_HOSTS = ["*"]
THIRD_PARTY_APP = [
"django_extensions",
] # 这里的第三方应用程序
INSTALLED_APPS = INSTALLED_APPS + THIRD_PARTY_APP
# 如果你想使用postgresql而不是sqlite3,请取消注释下方的postgresql部分,并注释掉sqlite3部分。
# DATABASES = {
# "default": {
# "ENGINE": "django.db.backends.postgresql_psycopg2",
# "NAME": env.str("DB_NAME"),
# "USER": env.str("DB_USER"),
# "PASSWORD": env.str("DB_PWD"),
# "HOST": env.str("DB_HOST"),
# "PORT": env.str("DB_PORT"),
# }
# }
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
Django项目
许多开发者通过执行命令在工作目录下创建自己的应用。
python3 manage.py startapp <app-name>
这会儿会让工作目录变得拥挤。
最佳做法在这里面,我们将Django应用创建在apps/
文件夹中。这样,所有的应用归在一处,便于查找。同时,这也让工作目录显得不那么拥挤。
要创建一个新的应用,我们这样做:
- 创建一个
apps/
文件夹 - 进入
apps/
文件夹然后运行startapp
命令
运行 `python3 ../manage.py startapp <app-name>` 来创建一个新的 Django 应用程序。这里 `<app-name>` 是你要创建的应用程序的名字。
注意:在执行 startapp
之后,应该跟上应用名。它不支持路径,因此我们需要先执行 cd
命令切换到 apps/
目录,然后通过 ../
来运行 manage.py
。
核心应用程序用来包含两个或多个应用程序共享的代码。
例如,模型通常共享相同的字段,例如created_at
,modified_at
。我们不再在每个模型中重复这些字段,而是可以将它们放在一个单独的应用中,并在需要时导入。
源代码路径: apps/core/abstracts/models.py
# apps/core/abstract_models.py
from django.db import models
class CreatedModifiedAbstract(models.Model):
created_time = models.DateTimeField(auto_now_add=True)
modified_time = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
请看:上面的代码定义了一个应该被其他模型继承的抽象类。
.
├── Django_First
**│ ├── apps
│ │ ├── __init__.py
│ │ └── core
│ │ ├── __init__.py
│ │ ├── abstracts
│ │ │ ├── __init__.py
│ │ │ └── models.py
│ │ └── apps.py**
│ ├── config
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings
│ │ │ ├── base.py
│ │ │ └── dev.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── manage.py
│ └── requirements
│ ├── base.txt
│ └── dev.txt
使用Makefile的命令快捷键
现在我们有了不同的结构,并且可以在不同的环境中运行我们的Django项目。我们需要输入较长的命令,因为每次运行时都需要指定环境。
为了给各种命令创建快捷方式,我们可以使用一个叫 Makefile
的文件。以下是我们在开发环境中常会用到的一些命令的快捷方式。
Makefile (一种用于自动化构建过程的文件)
dev-start:
python3 manage.py runserver --settings=config.settings.dev
dev-startapp:
cd apps && python3 ../manage.py startapp $(app) --settings=config.settings.dev
dev-migrate:
python3 manage.py migrate --settings=config.settings.dev
dev-makemigrations:
python3 manage.py makemigrations --settings=config.settings.dev
dev-dbshell:
python3 manage.py dbshell --settings=config.settings.dev
dev-shell:
python3 manage.py shell --settings=config.settings.dev
dev-shell-plus:
启动增强shell模式: (shell_plus)
python3 manage.py shell_plus --settings=config.settings.dev
dev-install:
运行依赖安装命令: pip install -r requirements/dev.txt
dev-test:
运行测试命令: python3 manage.py test --settings=config.settings.dev
要运行Makefile中的某个命令,我们只需键入make <command-name>
,其中<command-name>
是在Makefile中定义的一个快捷命令。例如,如果我们想启动Django服务器,可以运行make start
命令。
make 启动开发
总之:
Django 框架是创建复杂 web 应用程序的强大工具。然而,许多开发人员在项目结构的构建上遇到困难,这影响了他们的工作效率。
这篇文章遵循了最佳实践的结构,提供了一个样板,可用于构建一个Django项目。这使得任何Django项目的扩展变得简单。
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章