
0. 前言这篇文章干啥的用 python 的 Django 开发 web 应用涉及很多命令、代码套路。我懒得记了专门写一篇总结。用于速查命令开发过程中可参考不定期更新牢记这个图1. python 环境1.1 系统的 python 环境# 添加 PPAsudoadd-apt-repository ppa:deadsnakes/ppasudoaptupdate# 安装 Python 3.11sudoaptinstallpython3.11 python3.11-venv python3.11-dev# 验证python3.11--version1.2 项目的 python 环境# 项目环境cd项目路径 python3.11-mvenv .venv1.3 导入 python 包在 项目的 python 环境中进行操作# 激活环境 首次source.venv/bin/activate# 更新 pip首次python-mpipinstall--upgradepip# 导入包pipinstalldjango~4.2.0 python3-mpipinstallblack1.4 python 依赖 requirements.txt打包成 requirements.txtpip freezerequirements.txt用 requirements.txt 导入包pipinstall-rrequirements.txt2. 创建初始项目项目名称learn_django2.1 创建项目django-admin startproject learn_django.注意项目名称假设我们的整体项目叫做 learn_django那么 github 创建仓库时也叫这个然后使用 startproject 命令的时候也叫这个因为目前我在某个云服务器中使用时发现这样做的话部署时改动小2.2 初始化数据库本地SQLite数据库命令行python manage.py migrate代码learn_django/settings.py的 DATABASES 变量方式1直接使用本地数据库学习期使用DATABASES{default:{ENGINE:django.db.backends.sqlite3,NAME:BASE_DIR/db.sqlite3,}}方式2根据 环境变量 适配不同的数据库推荐详见2.3 节.env 文件中的DATABASE_URL 环境变量settings.py 代码中的DATABASES 字典2.3 环境变量配置导入environs包python-mpipinstallenvirons[django]在项目根目录下创建 .env 文件.env 内容这里配置的是 环境变量DATABASE_URLpostgres://用户名:密码localhost:5432/数据库名DEBUGFalseSECRET_KEYxxxALLOWED_HOSTSabc.comCSRF_TRUSTED_ORIGINShttp://abc.com注1 - DATABASE_URLDATABASE_URL 用于数据库开发环境中可以用DATABASE_URLsqlite3我在代码中做了适配这里的 DATABASE_URL 格式是用于 PostgreSQL 的它的创建可以看第 9.2 节注2 - SECRET_KEY部署阶段用以下命令生成python-cimport secrets; print(secrets.token_urlsafe())注3ALLOWED_HOSTS 防 Host 头攻击CSRF_TRUSTED_ORIGINS 防跨站伪造在开发环境中用 # 注释掉或者像这样配置ALLOWED_HOSTSlocalhost,127.0.0.1CSRF_TRUSTED_ORIGINShttp://localhost,http://127.0.0.1在生产环境中按照部署平台 实际提供的 URL 进行配置同步修改一下 learn_django/settings.py也就是读取环境变量fromenvironsimportEnv# newenvEnv()# newenv.read_env()# new...# SECURITY WARNING: keep the secret key used in production secret!SECRET_KEYenv.str(SECRET_KEY)# SECURITY WARNING: dont run with debug turned on in production!DEBUGenv.bool(DEBUG,defaultFalse)ALLOWED_HOSTSenv.list(ALLOWED_HOSTS,default[localhost,127.0.0.1])...DB_URL_STRenv.str(DATABASE_URL,default)ifsqlite3inDB_URL_STR:DATABASES{default:{ENGINE:django.db.backends.sqlite3,NAME:BASE_DIR/db.sqlite3,}}else:DATABASES{default:env.dj_db_url(DATABASE_URL),}...CSRF_TRUSTED_ORIGINSenv.list(CSRF_TRUSTED_ORIGINS,default[http://localhost,http://127.0.0.1])3. 创建 APPAPP名称posts3.1 创建 APPpython manage.py startapp posts3.2 修改 settings.pylearn_django/settings.py搜变量INSTALLED_APPSINSTALLED_APPS[django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,pages,posts,# new]4. 开发 APP4.1 模型 数据库posts/models.py只是个简例fromdjango.dbimportmodelsclassPost(models.Model):textmodels.TextField()def__str__(self):returnself.text[:50]# 数据条目名称显示前 50 个字符模型更新后注posts 是 APP 名称python manage.py makemigrations posts python manage.py migrate场景需要执行的命令第一次创建模型makemigrations→migrate添加/修改/删除字段makemigrations→migrate新建了 app 并添加 modelsmakemigrations→migrate拉取了别人的代码已有迁移文件只需migrate切换新数据库如 SQLite → PostgreSQL只需migrate4.2 模版创建 templates/ 文件夹首次在 templates/ 文件夹中写 html 模版目前可以参考《【Web应用开发笔记】Django笔记3模版的用法-实现一个简单的网页》这篇博客“2.3.3 ★ 解析 ★” 这一小节修改learn_django/settings.py变量TEMPLATESTEMPLATES[{BACKEND:django.template.backends.django.DjangoTemplates,DIRS:[BASE_DIR/templates# new ],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,],},},]4.3 图视posts/views.py 只是个简例fromdjango.views.genericimportListViewfrom.modelsimportPostclassHomePageView(ListView):modelPost template_namehome.html4.4 URL配置posts/urls.pyfromdjango.urlsimportpathfrom.viewsimportHomePageView urlpatterns[path(,HomePageView.as_view(),namehome),# important]learn_django/urls.pyfromdjango.contribimportadminfromdjango.urlsimportpath,include urlpatterns[path(admin/,admin.site.urls),path(,include(pages.urls)),path(,include(posts.urls)),# new]5. 管理员登录后台数据库5.1 代码posts/admin.pyfromdjango.contribimportadminfrom.modelsimportPost# new是 模型 中定义的类admin.site.register(Post)# new5.2 用户密码设置python manage.py createsuperuser5.3 登录 操作启动服务并通过浏览器访问 url启动服务开发环境详见 7.1节python manage.py runserver生产环境详见 8.4节urlhttp://127.0.0.1:8000/admin/6. 测试6.1 各 APP 写测试代码基础知识测试类用途数据库支持SimpleTestCase测试不依赖数据库的基本功能URL、视图、模板❌ 不创建测试数据库TestCase测试依赖数据库的功能模型、表单、数据库操作✅ 自动创建并隔离测试数据库LiveServerTestCase启动真实服务器进行集成测试如 Selenium 测试✅ 支持TransactionTestCase测试数据库事务行为✅ 每个测试后回滚事务继承4个基础类中的某一个写测试函数类的成员函数。Django 基于 Python 的 unittest 框架只要求遵循一个约定函数名必须以 test_ 开头posts/tests.py只是个简例fromdjango.testimportTestCase# important根据 APP 的实际情况选择fromdjango.urlsimportreverseclassHomepageTests(TestCase):deftest_url_exists_at_correct_location(self):responseself.client.get(/)# url 绝对路径self.assertEqual(response.status_code,200)deftest_url_available_by_name(self):responseself.client.get(reverse(home))# 根据名称反推 url 路径self.assertEqual(response.status_code,200)deftest_template_name_correct(self):responseself.client.get(reverse(home))self.assertTemplateUsed(response,home.html)deftest_template_content(self):responseself.client.get(reverse(home))self.assertContains(response,h1Homepage/h1)self.assertContains(response,h2Message board homepage/h2)6.2 运行测试代码python manage.pytest6.3 问题排查 修复查看上一步打印出的信息有哪些样例没通过报错信息是什么7. 开发环境启动服务 验证7.0 关于端口设置learn_django/settings.py 的 ALLOWED_HOSTS这只是简例ALLOWED_HOSTS[127.0.0.1,localhost,xxx.pythonanywhere.com]7.1 启动服务# 默认端口 8000 - http://127.0.0.1:8000/python manage.py runserver# 指定端口 - http://127.0.0.1:8080/python manage.py runserver80807.2 人工测试浏览器进入相应的 url比如是http://127.0.0.1:8000/然后进行功能使用 记录7.3 上库关于将本地项目变成 github 项目先在 github 上创建一个空项目不带 README.md在 github 中进行 SSH token 配置具体过程不赘述可以问 AI本地项目中进行初始化 gitcd/path/to/your/projectgitinit新建 .gitignore 文件内容如下.venv *__pycache__ staticfiles在我们的私人仓库上可以这样配置如果是公开的仓库需要把 .env 也加进去此时 .gitignore 内容如下.venv *__pycache__ staticfiles .env提交到缓存区 本地仓库gitadd.gitcommit-mxxx连接远程仓库ssh前置条件github 网站中进行操作为我们的设备配置 SSH token具体过程不赘述可以问 AIgitremoteaddorigin gitgithub.com:XXX/learn_django.git推到远程仓库gitpush origin master8. 生产环境 部署8.0 三种流程开发环境一切由 Django 负责性能差不可用于部署生产环境1 - WSGI/ASGI WhiteNoise常用于 PaaS 平台性能还行适合 MVP、小项目生产环境2 - Nginx WSGI/ASGI常用于 IaaS 平台高性能8.1 WSGIGunicorn 包Gunicorn 是 Django 本地 WSGI 服务器的生产替代方案。python-mpipinstallgunicorn20.1.08.2 WhiteNoise作为 Django 中间件用于处理静态文件。8.2.1 导入 whitenoise 包python-mpipinstallwhitenoise6.12.0更新 requirements.txtpip freezerequirements.txt8.2.2 修改代码learn_django/settings.pyINSTALLED_APPS[django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,whitenoise.runserver_nostatic,# new 1django.contrib.staticfiles,pages,posts,]MIDDLEWARE[django.middleware.security.SecurityMiddleware,whitenoise.middleware.WhiteNoiseMiddleware,# new 2django.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,]...STATIC_URLstatic/STATICFILES_DIRS[BASE_DIR/static]STATIC_ROOTBASE_DIR/staticfilesSTORAGES{# new 3 startdefault:{BACKEND:django.core.files.storage.FileSystemStorage,},staticfiles:{BACKEND:whitenoise.storage.CompressedManifestStaticFilesStorage,},}# new 3 end注意上述代码中的 MIDDLEWARE 列表里面各个中间件的顺序很重要。因为中间件是 链式调用 的像流水线。简要学习 可以看《【Web应用开发笔记】Django笔记5-2基础概念Nginx、WSGI、中间件、静态文件》第4节官方文档Enable WhiteNoise8.3 关于静态文件代码learn_django/settings.py 的 STATIC_ 相关变量STATIC_URLstatic/STATIC_ROOTBASE_DIR/staticfiles# new如果我们新增了 static/ 文件夹并在其中添加了相关静态文件我们需要如下配置STATIC_URLstatic/STATICFILES_DIRS[BASE_DIR/static]# newSTATIC_ROOTBASE_DIR/staticfiles最后通过 命令行 自动收集静态文件python manage.py collectstatic8.4 本地启动 验证修改代码learn_django/settings.py用于 摆脱开发环境DEBUGFalse8.4.1 选型1WSGI (Gunicorn) WhiteNoise启动注意下面命令的 learn_django 是项目名需要根据实际项目进行调整gunicorn learn_django.wsgi:application--bind0.0.0.0:8000验证主页http://127.0.0.1:8000/静态文件http://127.0.0.1:8000/static/admin/css/base.css8.5 .dockerignore 文件在项目根目录下。内容如下.venv/ __pycache__/ *.sqlite3 .git .env8.x 云服务器平台8.x.0 当前导入的包pipinstalldjango~4.2.0# Djangopipinstallblack# 代码格式化工具开发用保持统一代码风格pipinstallenvirons[django]# 用于读取环境变量pipinstallgunicorn20.1.0# WSGIpipinstallpsycopg[binary]3.1.8# 访问 PostgreSQL 数据库注意不同类型数据库用的驱动包不一样pipinstallwhitenoise6.12.0# WhiteNoise 中间件8.x.1 PythonAnywhere部署过程在 PaaS 平台的终端 或者 前端进行操作step 1: 更新代码git clone可能需要在平台做 SSH 相关配置step 2: 导入依赖按照 requirements.txt注意使用哪个 python比如在PaaS平台选择环境时可能会选择 python版本那么在终端操作就需要找对 python# 形如python3.11-mpipinstall-rrequirements.txt这里的 python3.11 是我学习过程中使用并在 PaaS 平台选择的实际需要根据部署时的实际情况进行选择形如python、python3.12等你可以使用形如which python3.11的命令来查看需要的 python 版本是否存在step 3: 配置 .env 文件五个参数如前面的 3.1 节所述step 4: 数据库相关操作migrate、createsuperuser注意要使用托管数据库服务以及专门为生产环境创建的数据库由于我们使用的数据库与生产环境不是同一个需要依次执行 migrate、createsuperuser# 刷新数据库python3.11 manage.py makemigrations posts python3.11 manage.py migrate# 创建管理员python3.11 manage.py createsuperuserstep 5: 静态文件collectstatic执行 collectstatic 自动收集静态文件python3.11 manage.py collectstatic注由于 staticfiles/ 可以由这个命令自动生成故此我在 git 上库中将其忽略所以在部署时需要执行 collectstatic 来生成这个文件夹step 6: 重启服务step 7: 测试 问题修复功能测试进行静态文件访问 主页URL/static/admin/css/base.css补充有些平台可能在前端配置的时候就可以配环境变量博客《【Web应用开发笔记】Django笔记3-2部署我的简陋网页》 这篇博客“2.1 PythonAnywhere” 小节《Web应用开发笔记】Django笔记5-3Gunicorn、WhiteNoise 与部署》“3. 部署” 小节9. 数据库对于生产环境数据库十分重要。我们需要一些前置工作这在2.3 节中有介绍我们已经配置了环境变量DATABASE_URL它具体的内容与实际采用的数据库进程有关在下面的小节里不同的数据库中会提到修改了 settings.py 中的 DATABASES 字典9.1 本地数据库 SQLite.env 文件中删除 DATABASE_URL 环境变量配置。此外按照 “★ 创建数据库后的通用操作 ★” 进行操作即可。9.2 数据库PostgreSQLstep1: 导入postgresql# 1. 更新软件包列表sudoaptupdate# 2. 安装 PostgreSQL 及常用工具sudoaptinstallpostgresql postgresql-contrib# 3. 检查安装状态看看服务是否运行显示 active (exited) 即正常sudosystemctl status postgresqlstep2: 导入Pyscopg包一个数据库适配器可以让 Python 应用程序与 PostgreSQL 数据库进行通信python3-mpipinstallpsycopg[binary]3.1.8step3: 创建数据库进入操作界面仍在终端中sudo-upostgres psql创建数据库数据库名是小写CREATE DATABASE 数据库名;创建用户CREATEUSER用户名 WITH PASSWORD你的密码;授权GRANT ALL PRIVILEGES ON DATABASE 数据库名 TO 用户名;# 退出\q# 登录到具体数据库sudo-upostgres psql-d数据库名# 在 psql 中执行GRANT ALL ON SCHEMA public TO 用户名;GRANT ALL PRIVILEGES ON DATABASE snapcover TO 用户名;ALTER DATABASE snapcover OWNER TO 用户名;\q如果测试代码涉及 新建数据库则需要配置如下权限ALTERUSER用户名 CREATEDB;查看# 列出所有数据库\l# 列出所有用户\du# 退出\qstep4: 配置项目的 环境变量正如 2.3 节 中介绍的在 .env 文件中配置 DATABASE_URL 环境变量形如DATABASE_URLpostgres://用户名:密码localhost:5432/数据库名9.x★ 创建数据库后的通用操作 ★更换数据库后的操作# 刷新数据库python manage.py makemigrations posts python manage.py migrate# 创建管理员python manage.py createsuperuser修改模型后的通用操作python manage.py makemigrations posts python manage.py migrate管理员登录数据库看第5节 管理员登录后台数据库