Django Web 应用项目:学习笔记

  前言

学习框架

此文说明

  1. 此项目参考于《Python编程:从入门到实践》_第1版_Eric Matthes 中的 “Web应用程序:学习笔记”项目。
  2. 此项目文件名为 learning_log, 文中涉及的路径都以 learning_log/ 开头。

为什么学

  1. 完成《Python编程:从入门到实践》中的 “Web应用程序:学习笔记”项目
  2. 学习 Python Web应用开发,了解 Django 开发框架
  3. 熟悉 Linux 开发环境
  4. 掌握 HTML 网页设计知识
  5. 学习 Web 项目部署

背景知识
关系数据库基础知识。
HTML 基础知识

参考文档
Django 官网: https://docs.djangoproject.com/en/4.0/
django中文网: https://www.django.cn/course/
uwsgi: https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/WSGIquickstart.html
书中有更新的内容: https://ehmatthes.github.io/pcc/updates.html

  实现过程

Django 内置模块

以下模块名均省略 django. 前缀,均是项目中涉及到的模块

Module(模块) Inclusion(包含) Explanation(解释)
http HttpRequest、HttpResponse、Http404... http 请求与响应模块
db.< name > models(数据模型)... Django 数据库系统
db.models Model 一个模型对应一张数据库关系表
db.models.fields Charfield、TextField... 模型字段,对应于数据库关系表的列属性
db.backends mysql、sqlite3、postgresql... Django 支持的数据库后端(引擎)
db.migrations Migration Django 将你对模型所做的更改(添加一个字段,删除一个模型)映射到数据库模式中的一种方式
contrib.< name > admin(网站管理)、auth(用户认证及授权)、messages(消息管理)... abbr. 贡献(contribution)。包含解决常见 web 开发问题的可选工具,每个工具都是一个应用程序,使用时包含在 settings.py 中的 INSTALLED_APPS 里。
contrib.auth Django 认证系统,处理用户认证和授权。
contrib.auth.models User、Group、Permission... 用户认证和授权相关的模型(类)及函数
contrib.auth.decorators login_required()... 装饰器
contrib.staticfiles 静态文件管理

models 与 database 的关系

MVC Web 框架中的 M 即是 models,而 models 直接定义和操纵数据库,所以任何涉及数据存储与交互的 Web 应用都会用到 models。

在 Python 中的 Django Web 框架中,models 里面会定义一些类,一般每一个类对应于数据库中的一张关系表。Django 默认使用 <小写类名>_id作为这张表的主键。因此在代码中可以直接使用这个“未定义”的关键字。举例如下:

在 models.py 中定义一个 Topic 类:

class Topic(models.Model):
	"""A topic the user is learning about"""
	text = models.CharField(max_length=200)

在 urls.py 中使用基于 Topic 类创建的关系表的 主键关键字 topic_id:

urlpatterns = [
	# Detail page for a single topic
	path('topics/<int:topic_id>/', views.topic, name='topic'),
]

  项目部署

基本概念

1. 什么是项目部署

应用程序的完成至少有两个阶段,开发和部署。

所谓部署,就是让开发出的产品能够在某一环境中运行起来。

将开发过程中产生的源代码生成可运行的软件包,然后将软件包放到要部署的环境中,通过一些配置使得这个软件包在目标环境上也能够正常工作,这就是完整的部署过程。

这个环境是什么?可以是公司的实体服务器(机房里的服务器),可以是云服务器,也可以是本地服务器(个人电脑),所以相应地部署就分为远程部署和本地部署。


2. 为什么要部署项目

对于一个项目来说,不同人群需要的“产品”类型不一样。假设我们要为某一个公司开发一个网站,开发人员关心的是源代码,而项目管理人员要的是一个可运行的软件包,客户要的是打开网页就能显示预期内容的页面。

我们之所以部署项目,就是想达到客户的访问要求,即看到网站的内容。

开发工作是在本地进行的,这时我们会使用一些编辑器,如 VScode 等,但是这时项目只能在我们本地环境才能正常运行,别人的电脑是访问不到的,要想别人也能够正常使用我们的项目就得进行项目部署


3. 如何部署项目

部署要做的工作大致分为三步:

  1. 将源代码打包成 .jar 包或 .war 包
  2. 将可运行的软件包放到部署平台上
  3. 配置部署环境,使软件包运行起来

一般来说,我们提到的部署都是远程部署,真正地投入用户使用。

服务器、域名、ICP备案

按如下步骤准备:

  1. 服务器
    购买腾讯云服务器:轻量应用服务器 Linux CentOS 8.0 2核2G4M 300GB/月 (65元/年)

  2. 域名
    lightmark.club 光印网 (12/年)
    轻松而自由,每笔皆印记。For relax and freedom, every letter is a mark!

  3. ICP备案
    域名购买成功并实名认证后等待3天,在腾讯云官网备案即可。
    注意!!!ICP 备案成功后再进行域名解析。

  4. 域名解析
    腾讯云官网 DNS 解析。

Git 版本控制系统

1. 安装配置 Git

如何学习 Git

  • 初步了解 Git :
    参考《Python编程:从入门到实践》附录D :使用 Git 进行版本控制。在正式进行项目部署前,通过一个小案例进行 Git 学习。
  • 官网文档:
    https://git-scm.com/site
    https://git-scm.com/doc

安装及配置 Git

  1. 安装参考:https://git-scm.com/download/linux
  2. 官方说 RHEL 一般自带 Git:RHEL(Red Hat Enterprise Linux) and derivatives typically ship older versions of git.
  3. 查看 CentOS 是否自带 Git
    1. rpm 安装的,可以用 rpm -qa 查找。如果要查找某软件包是否安装,用 rpm -qa|grep < packagename >
      yum list installed |grep git
      git-core-2.27.0-1.el8.x86_64
      !!!如果没有返回值则表示没有安装。
    2. yum 安装的,可以用 yum list installed 查找。如果是查找指定包,命令后加 |grep < packagename >
      yum list installed |grep git
      git.x86_64 2.27.0-1.el8 @AppStream
      !!!如果没有返回值则表示没有安装。
    3. 如果是用 源码包 编译安装的,例如.tar.gz或者tar.bz2形式的,这个只能看可执行文件是否存在了,上面两种方法都看不到这种源码形式安装的包。
    4. 如果是以 root 用户安装的,可执行程序通常都在 /sbin/usr/bin 目录下。
  4. 如果没有安装,用 yum install git 或 用源代码编译安装。
  5. 配置 Git。配置 Git 的目的是让 Git 知道谁修改了项目,方便 Git 进行版本跟踪。
    关于配置 Git 的详细说明: https://git-scm.com/docs/git-config
    Git 基本配置:https://training.github.com/downloads/zh_CN/github-git-cheat-sheet/

2. Git 使用流程

  1. 进行配置
    查看配置列表。 git config --list 如果之前没有进行任何配置,则直接进入新的命令行。
    配置相关的命令。git config 获取所有可选命令。或者查阅参考手册。
    参考:对给git配置邮箱和用户名的理解 https://blog.csdn.net/ITWANGBOIT/article/details/103618427

     git config --global user.name "username"
     git config --global user.email "username@example.com
    
  2. 忽略无需跟踪的文件
    参考《Python编程:从入门到实践》附录 D:D.3 忽略文件

  3. 初始化仓库
    在项目文件夹中执行命令git init。我的项目文件夹是 C:\Users\dell\learning_log(即 manage.py 所在文件夹)。!!!注意,创建的是一个 .git 文件夹,以 . 开头的文件一般会默认隐藏,请用 ls -a 查看是否添加成功。

  4. 检查状态
    执行命令 git status

  5. 将文件添加到仓库中
    执行命令 git add . !!! 注意,不要忘记句点,每次添加完请用 git status 检查一下状态。命令git add .将项目中未被跟踪的所有文件都加入到仓库中,它不提交这些文件,而只是让 Git 开始关注它们。!!!注意,如果你在两次提交之间创建了新文件,可再次执行命令 git add . 将这些新文件加入到仓库中。

  6. 执行提交
    执行命令 git commit -m ["descriptive message"]。标志 -m 让 Git 将接下来的消息,(比如,"Started project.")记录到项目的历史记录中。每次提交完请用 git status 检查一下状态,有 nothing to commit, working directory clean 则表示提交成功 。

  7. 查看提交历史
    执行命令 git log

  8. 修改后再次提交
    执行命令 commit -am ["descriptive message"]。标志 -a 让 Git 将仓库中所有修改了的文件都加入到当前提交中(如果你在两次提交之间创建了新文件,可再次执行命令 git add . 将这些新文件加入到仓库中)。标志 -m 让 Git 在提交历史中记录一条消息。

  9. 撤销修改(恢复到上一次快照)
    命令git checkout让你能够恢复到以前的任何提交。命令git checkout .放弃自最后一次提交后所做的所有修改,将项目恢复到最后一次提交的状态。

  10. 检出以前的提交,删除仓库
    参考《Python编程:从入门到实践》附录 D:D.11、D.12

Web 服务器

1. 关于 wsgi 与 asgi

参考文档:https://docs.djangoproject.com/zh-hans/4.0/howto/deployment/

LNMP 和 LAMP 是目前最流行的 Web 应用部署方案,这里的 P 基本是指 PHP ,当然也可以是 Python。常见的 Web 服务器有 Apache Web server、Nginx、Tomcat、Lighttpd...

部署 Django 应用程序有很多选择,可以基于架构或者特定的业务需要选择部署方案。

Django 是一个需要 Web 服务器来运行的 Web 框架。然而由于大多数 Web 服务器不是用 Python 编写的,因此我们需要一个接口来实现沟通。

Django 现在支持两种接口:WSGI 和 ASGI。在项目的 settings.py 所在的目录有 Django 自动生成的 Web 接口脚本,即 wsgi.py 和 asgi.py。

  • WSGI 是 Python 的主要接口标准,用于网络服务器和应用程序之间的通信,但它只支持同步代码。
  • ASGI 是新兴的、对异步友好的、让 Django Web 应用使用 Python 异步特性的接口标准。

显然,我们的 Django 项目部署需要一个支持 wsgi 或 asgi 的 Web 服务器。支持 wsgi 接口的 Web 服务器通常叫 WSGI 服务器,asgi 同理。


2. 选择 Web 服务器

参考文档:https://docs.djangoproject.com/zh-hans/4.0/howto/deployment/

显然,我们可以按 Django 支持的接口类型选择 Web 服务器,因此,可以选择 WSGI 或 ASGI 进行部署。注意!!!选择以下任一方案中的任一服务器配置即可。

方案一:使用 WSGI 服务器部署

  1. Gunicorn:UNIX 下的纯 Python WSGI 服务器。
  2. uWSGI:快速的,自我驱动的,对开发者和系统管理员友好的应用容器服务器,完全由 C 编写。
  3. Apache + mod_wsgi:mod_wsgi 是一个 Apache 模块,它可以管理任何 Python WSGI 应用,包括 Django。

方案二:使用 ASGI 服务器部署

  1. Daphne:纯 Python 编写的应用于 UNIX 环境的由 Django 项目维护的 ASGI 服务器。
  2. Hypercorn:加强支持 HTTP/1,HTTP/2 和 HTTP/3 的 ASGI 服务器。
  3. Uvicorn:基于 uvloop 和 httptools 的加强运行速度的 ASGI 服务器。

管理与部署静态文件

1. 基础概念

网站通常需要提供类似图片,JavaScript 或 CSS 的额外文件服务。在 Django 中,我们将这些文件称为“静态文件”。Django 提供了 django.contrib.staticfiles 帮你管理它们。

参考文章

  1. Django 4.0 documentation, 4.17 How to manage static files (e.g. images, JavaScript, CSS)
    https://docs.djangoproject.com/zh-hans/4.0/howto/static-files/
  2. Django 4.0 documentation, 4.18 How to deploy static files
    https://docs.djangoproject.com/zh-hans/4.0/howto/static-files/deployment/
  3. Django 4.0 documentation, 6.5.12 The staticfiles app
    https://docs.djangoproject.com/zh-hans/4.0/ref/contrib/staticfiles/

2. 管理静态文件

详细内容参考:Django 4.0 documentation,4.17.1 Configuring static files,此处记录一些笔记。

在创建项目时,Django 在INSTALLED_APPS 里自动添加了 django.contrib.staticfiles 应用。
STATIC_URL = 'static/'所指的位置是项目根目录中 static 文件的位置,即 learning_log/learning_log/static/,注意!!!我们需要自己手动创建一个 static 文件夹,并在文件夹内创建一个placeholder.txt 文件作为占位符,里面写明这是静态文件所在位置即可(有些部署平台,如 Heroku,会在项目打包上传后会删除空文件夹)。


3. 部署静态文件

详细内容参考:
Django 4.0 documentation,4.17.7 Deployment
Django 4.0 documentation,4.18 How to deploy static files,介绍了三种常见的静态文件部署模式,此处学习其中一种。

无论是管理还是配置静态文件,都没有唯一的固定的方法和流程,具体情况具体分析。但是,了解常规的操作方法总是大有裨益的。

如何在同一服务器运行网站和提供静态文件服务? 操作步骤类似这样:

  1. 将代码推送至部署服务器。
  2. 在服务器上运行 collectstatic,将所有的静态文件拷贝至 STATIC_ROOT。
  3. 配置 Web 服务器,使其在 STATIC_URL 下为 STATIC_ROOT 目录下的文件提供静态文件服务。

  Bug 总结

1. 'ajango-admin.py'不是内部或外部命令,也不是可运行的程序或批处理文件。

书中作者是用 MacOS 开发的,我是用 Windows, 此处不用后缀 .py,直接使用 django-admin startproject < projectname >

配置环境变量,此处复制异常参考百度。注意!!!我的 django-admin.py 在 python 虚拟环境文件夹的 \Scripts 文件夹下,不在网络解答说的 \bin 文件夹下。一定要思考解答者的开发环境是否和自己一致。


2. TypeError: ForeignKey.\(\underline{~~}init\underline{~~}()\) missing 1 required positional argument: 'on_delete'

书中位置
P366 18.2.5 迁移模型 Entry

问题描述
终端执行命令(ll_env) C:\Users\dell\learning_log> python manage.py makemigrations learning_logs 后出现 TypeError: ForeignKey.\(\underline{~~}init\underline{~~}()\) missing 1 required positional argument: 'on_delete'

解决方法
先了解一下级联删除,级联删除是指当主表(parent table)中的一条记录被删除,子表中关联的记录也对应的主动删除。

在 Django2.0后,设置多对一关系时,必须要设置级联删除,也就是当你删除主表的记录时,会级联删除所有和这一条记录对应的子表中的多条记录。

< foreignkey_name> = models.ForeignKey(< parent_table >, on_delete=models.CASCADE)   # 添加 on_delete=models.CASCADE 参数

新版本指定 on_delete=models.CASCADE 参数就是为了达到级联删除的目的,在老版本这个参数on_delete=models.CASCADE 是默认值。

  开发日记

心态与方法

对于新手,《Python编程:入门与实践》这本书第一章到十一章的基础知识部分确实通俗易懂,非常棒。项目一的游戏和项目二的数据可视化也挺好,虽然自己需要扩展 pygame、matplotlib、pygal 的一些知识,但基本不涉及到 Linux 环境下的开发以及项目部署问题,心态上会好很多,对于项目三的 Web 应用开发和部署,我需要学习 Linux 工作环境和项目部署框架,这对于新手而言会比较不友好,所以在做项目三之前我需要做一些准备工作:

(1)简单通读一遍书中的项目开发和部署流程,扫清一些框架和整体认识上的盲点。
(2)注意参考书及软件版本迭代问题造成的开发和部署错误。比如:作者是用 MacOS 终端开发的,我用 Windows开发。
(3)心态一定要好,信念一定要坚定。

还是很喜欢王澍的这段话:一个好的建筑师,就是你一开始有一个很纯粹的、带有理想主义的想法,完了以后你要像长征一样的,经过很多的险阻,中间很多次都有人想摧毁你、否定你,你必须能够做到百折不挠,而且要说服大家。最后走到终点,你还保持了你最初理想的那个纯度,没有半分的减损,甚至更加的坚定,这就是一个好的建筑师。

阅读官方文档

我发现,完全按作者的步骤固然可以完成这个有趣的 Web 项目,但是会留下“十万个为什么”,面对网上大量碎片化而不甚权威的解答,我感到十分恼火,而且很多解答都是作者复制抄袭别人的,所以我决定阅读官方文档。这份完整的官方文档有足足2238页,可供下载的文档只有英文版,中文版只有在线文档,这对我的阅读是个挑战,所以,我必须掌握快速捕捉有用信息的能力,这有助于我提高开发效率。

我不应该抗拒阅读英文文档,因为优秀技术文档的第一手资料都是英文的,如果要获取最新的技术,就必须掌握英文阅读的能力,依赖翻译后的文档永远是落后的。

限制敏感页面的访问

Django 能够轻松地限制对页面的访问,但我们必须确定要保护哪些页面。最好先确定项目的哪些页面不需要保护,再限制对其他所有页面的访问。因为我们可以轻松地修改过于严格的访问限制,比起不限制对敏感页面的访问,这样做的风险更低。

posted @ 2022-07-13 10:58  BodhiLeaf  阅读(120)  评论(0编辑  收藏  举报