Django框架(1)

随着互联网的发展,网站和移动应用程序之间的界线不再清晰,它们都能够让用户以各种方式与数据交互。所幸,可以使用 Django 来创建能同时作为动态网站和移动应用程序的项目。Django 是最流行的 Python Web 框架,提供了一系列旨在帮助开发交互式网站的工具。本章介绍如何使用 Django 来开发一个名为"学习笔记"(Learning Log)的项目。这是一个在线日志系统,让你能够记录针对哪些特定主题学到了哪些知识。

我们将先为这个项目制定规范,再为使用的数据定义模型。我们将使用 Django 的管理系统来输入一些初始数据,然后编写视图和模板,让 Django 能够创建网页。

Django 能够响应网页请求,还让你能够更轻松地读写数据库、管理用户,等等。我们将改进"学习笔记"项目,再将其部署到活动的服务器上,让所有人都能够使用它。

1 建立项目

在着手开发像 Web 应用这样的大项目时,首先需要制定规范(spec),对项目的目标进行描述。确定要达成的目标后,就能着手找出为达成这些目标而需要完成的任务了。

本节将为"学习笔记"项目制定规范,并进入项目开发的第一个阶段,包括搭建虚拟环境以及构建 Django 项目框架。

1.1 制定规范

完整的规范要详细说明项目的目标,阐述项目的功能,讨论项目的外观和用户界面。与任何良好的项目规划书和商业计划书一样,规范应突出重点,帮助避免项目偏离轨道。这里不制定完整的项目规划,只列出一些明确的目标,以突出开发的重点。我们制定的规范如下:

我们要编写一个名为"学习笔记"的 Web 应用程序,让用户能够记录感兴趣的主题,并在学习每个主题的过程中添加日志条目。"学习笔记"的主页对这个网站进行描述,并邀请用户注册或登录。用户登录后,可以创建新主题、添加新条目以及阅读既有的条目。

在学习新主题时,记录学到的知识可有助于建立知识体系,研究技术主题时尤其如此。优秀的应用程序(如接下来将创建的应用程序)能让这个记录过程简单高效。

1.2 建立虚拟环境

使用 Django 之前,需要建立虚拟的工作环境。虚拟环境是系统的一个位置,你可在其中安装包,并将这些包与其他 Python 包隔离开来。将项目的库与其他项目分离是有益的,为了将"学习笔记"部署到服务器,这也是必须的。

为项目新建一个目录,将其命名为 learning_log,再在终端中切换到这个目录,并执行如下命令创建一个虚拟环境:

复制代码
learning_log$ python -m venv ll_env
learning_log$

这里运行了模块 venv,并使用它创建了一个名为 ll_env 的虚拟环境。(请注意,ll_env 的开头是两个小写的 L,而不是数字 1。)如果你在运行程序或安装包时使用的是命令 python3,这里也务必使用同样的命令。

创建好虚拟环境可以在文件夹看到这个文件

1.3 激活虚拟环境

现在需要使用下面的命令激活虚拟环境:

如果你使用的是 Windows 系统,请使用命令

ll_env\Scripts\activate(不包含 source)来激活这个虚拟环境。如果你使用的是 PowerShell,可能需要将 Activate 的首字母大写。

激活后可以看到是这样的。

要停止使用虚拟环境,可执行命令 deactivate:

复制代码
(ll_env)learning_log$ deactivate
learning_log$

1.4安装Django

激活虚拟环境后,执行如下命令来更新 pip 并安装 Django:

复制代码
(ll_env)learning_log$ pip install --upgrade pip
(ll_env)learning_log$ pip install django
Collecting django
--snip--
Installing collected packages: sqlparse, asgiref, django
Successfully installed asgiref-3.5.2 django-4.1 sqlparse-0.4.2
(ll_env)learning_log$

如图所示

pip 从各种地方下载资源,因此升级频繁。有鉴于此,每当你搭建新的虚拟环境后,都最好更新 pip。

由于现在是在虚拟环境中工作,因此不管使用什么系统,安装 Django 的命令都相同:不需要指定标志 --user,也无须使用像 python -m pip install package_name 这样较长的命令。别忘了,Django 仅在虚拟环境 ll_env 处于活动状态时才可用。

注意:每隔大约 8 个月,Django 新版本就会发布,因此你在安装 Django 时,看到的可能是更新的版本。即便你使用的是更新的 Django 版本,这个项目也可行。如果要使用这里所示的 Django 版本,请使用命令 pip install django==4.1.*,这将安装最新的 Django 4.1 版本。如果你在使用更新的版本时遇到麻烦,请参阅本书的在线资源。

1.5 在Django中创建项目

在虚拟环境依然处于活动状态的情况下(ll_env 包含在括号内),执行如下命令新建一个项目:

复制代码
(ll_env)learning_log$ django-admin startproject ll_project .
(ll_env)learning_log$ ls
ll_env  ll_project  manage.py
(ll_env)learning_log$ ls ll_project
__init__.py  asgi.py  settings.py  urls.py  wsgi.py

命令 startproject(见❶)让 Django 新建一个名为 ll_project 的项目。这个命令末尾的句点(.)让新项目使用合适的目录结构,这样在开发完成后可轻松地将应用程序部署到服务器上。

注意:千万别忘了这个句点,否则在部署应用程序时将遭遇一些配置问题。如果忘记了,需要删除已创建的文件和文件夹(ll_env 除外),再重新运行这个命令。

在❷处,运行命令 ls(在 Windows 系统上为 dir),结果表明 Django 新建了一个名为 ll_project 的目录。它还创建了文件 manage.py,这是一个简单的程序,接受命令并将其交给 Django 的相关部分。我们将使用这些命令

目录 ll_project 包含 4 个文件(见❸),其中最重要的是 settings.pyurls.pywsgi.py。文件 settings.py 指定 Django 如何与系统交互以及如何管理项目。在开发项目的过程中,我们将修改其中的一些设置,并添加一些设置。文件 urls.py 告诉 Django,应创建哪些网页来响应浏览器请求。文件 wsgi.py 帮助 Django 提供它创建的文件,名称是 web server gateway interface(Web 服务器网关接口)的首字母缩写。

如图所示创建完成后文件夹可以看到ll_project文件夹(ll_env是我们的虚拟环境)

从PyCharm打开。

可以看到一些自带的python文件。

1.6 创建数据库

Django 将大部分与项目相关的信息存储在数据库中,因此需要创建一个供 Django 使用的数据库。为了给项目"学习笔记"创建数据库,要在虚拟环境处于活动状态的情况下执行下面的命令:

复制代码
(ll_env)learning_log$ python manage.py migrate
① Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  --snip--
  Applying sessions.0001_initial... OK
② (ll_env)learning_log$ ls
db.sqlite3  ll_env  ll_project  manage.py

出现这个界面说明成功了。

出现db.sqlite3说明数据库迁移成功。

我们将修改数据库称为迁移 (migrate)数据库。首次执行命令 migrate将让 Django 确保数据库与项目的当前状态匹配。在使用 SQLite(后面将详细介绍)的新项目中首次执行这个命令时,Django 将新建一个数据库。在这里,Django 指出它将准备好数据库,用于存储执行管理和身份验证任务所需的信息(见❶)。

❷处运行了命令 ls,其输出表明 Django 又创建了一个文件,名为 db.sqlite3。SQLite 是一种使用单个文件的数据库,是编写简单应用程序的理想选择,因为它让你不用太关注数据库的管理问题。

注意 :在活动的虚拟环境中运行 manage.py时,务必使用命令 python,即便你在运行其他程序时使用了命令 python3也是如此。在虚拟环境中,命令 python指的是在创建虚拟环境时使用的 Python 版本。

1.7 查看项目

下面来核实 Django 正确地创建了项目。为此,可使用命令 runserver 查看项目的状态:

复制代码
(ll_env)learning_log$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

① System check identified no issues (0 silenced).
  May 19, 2022 - 21:52:35
② Django version 4.1, using settings 'll_project.settings'
③ Starting development server at http://127.0.0.1:8000/
  Quit the server with CONTROL-C.

Django 启动一个服务器(development server),让你能够查看系统中的项

到这一步说明启动成功了,复制127.0.0.1:8000到浏览器打开。

Django 启动一个服务器(development server),让你能够查看系统中的项目,了解它的工作情况。如果你在浏览器中输入 URL 以请求网页,那么该 Django 服务器将进行响应:生成合适的网页,并将其发送给浏览器。

Django 首先通过检查确认正确地创建了项目(见❶),然后指出使用的 Django 版本以及当前使用的设置文件的名称(见❷),最后指出项目的

URL(见❸)。URL http://127.0.0.1:8000/表明项目将在你的计算机(即 localhost)的端口 8000 上侦听请求。localhost 表示只处理当前系统发出的请求的服务器,它不允许其他人查看正在开发的网页。

现在打开一款 Web 浏览器,输入 URL http://localhost:8000/(如果不管用,请输入 http://127.0.0.1:8000/)。你将看到一个类似于图 18-1 的页面。这个页面是 Django 创建的,让你知道到目前为止一切正常。现在暂时不要关闭这个服务器,等到要关闭时,可切换到执行命令 runserver 时所在的终端窗口并按 Ctrl + C。

显示这个界面说明启动成功了。

2 创建应用程序

Django 项目(project)由一系列应用程序组成,它们协同工作让项目成为一个整体。本章只创建一个应用程序,它将完成项目里的大部分工作。第 19 章将添加一个管理用户账户的应用程序。

当前,在前面打开的终端窗口中应该还运行着 runserver。请再打开一个终端窗口(或标签页),并切换到 manage.py 所在的目录。激活虚拟环境,然后执行命令 startapp:

复制代码
learning_log$ source ll_env/bin/activate
(ll_env)learning_log$ python manage.py startapp learning_logs
① (ll_env)learning_log$ ls
db.sqlite3  learning_logs  ll_env  ll_project  manage.py
② (ll_env)learning_log$ ls learning_logs/
__init__.py  admin.py  apps.py  migrations  models.py  tests.py  views.py

命令 startapp appname让 Django 搭建创建应用程序所需的基础设施。如果现在查看项目目录,将看到其中新增了文件夹 learning_logs(见❶)。使用命令 ls查看 Django 都创建了什么(见❷),其中最重要的文件是 models.pyadmin.pyviews.py。我们将使用 models.py来定义要在应用程序中管理的数据,稍后再介绍 admin.pyviews.py

2.1 定义模型

我们来想想涉及的数据。每个用户都需要在学习笔记中创建很多主题。用户输入的每个条目都与特定的主题相关联,这些条目将以文本的方式显示。还需要存储每个条目的时间戳,以便告诉用户各个条目都是什么时候创建的。

开始前把python环境换成learning_log里面的环境。

打开文件 models.py,看看它当前包含哪些内容:

models.py

复制代码
from django.db import models

# 在这里创建模型

这里导入了模块 models,并让我们创建自己的模型。模型告诉 Django 如何处理应用程序中存储的数据。模型就是一个类,就像前面讨论的每个类一样,包含属性和方法。下面是表示用户将存储的主题的模型:

复制代码
from django.db import models

class Topic(models.Model):
    """用户学习的主题"""
    text = models.CharField(max_length=200)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        """返回模型的字符串表示"""
        return self.text

这里创建一个名为 Topic 的类,它继承了 Model,即 Django 中定义了模型基本功能的类。我们给 Topic 类添加了两个属性:text 和 date_added。

就像这样。

属性 text 是一个 CharField------由字符组成的数据,即文本(见❶)。当需要存储少量文本(如名称、标题或城市)时,可使用 CharField。在定义 CharField 属性时,必须告诉 Django 该在数据库中预留多少空间。这里将 max_length 设置成了 200(即 200 个字符),这对于存储大多数主题名来说足够了。

属性 date_added 是一个 DateTimeField------记录日期和时间的数据(见❷)。我们传递了实参 auto_now_add=True,每当用户创建新主题时,Django 都会将这个属性自动设置为当前的日期和时间。

最好告诉 Django,你希望它如何表示模型的实例。如果模型有 __str__()方法,那么每当需要生成表示模型实例的输出时,Django 都将调用这个方法。这里编写了 __str__()方法,它返回属性 text 的值(见❸)。

要 了解可在模型中使用的各种字段,请参阅 Django Model Field Reference(Django 模型字段参考)。就当前而言,你无须了解其中的全部内容,但在你自己开发 Django 项目时,这些内容将提供极大的帮助。

2.2 激活模型

要使用这些模型,必须让 Django 将前述应用程序包含到项目中。为此,打开 settings.py(它位于目录 ll_project 中),其中有个片段告诉 Django,哪些应用程序被安装到了项目中:

settings.py

python 复制代码
--snip--
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
--snip--

请将 INSTALLED_APPS 修改成下面这样,将前面的应用程序添加到这个列表中:

python 复制代码
--snip--
INSTALLED_APPS = [
    # 我的应用程序
    'learning_logs',

    # Django 默认添加的应用程序
    'django.contrib.admin',
    --snip--
]
--snip--

这样就完成了。

通过将应用程序编组,在项目因规模不断扩大而包含更多应用程序时,有助于对应用程序进行跟踪。这里新建了一个名为 My apps 的片段,当前它只包含应用程序 learning_logs。务必将你自己创建的应用程序放在默认应用程序前面,这样能够覆盖默认应用程序的行为。

接下来,需要让 Django 修改数据库,使其能够存储与模型 Topic 相关的信息。为此,在终端窗口中执行如下命令:

复制代码
(ll_env)learning_log$ python manage.py makemigrations learning_logs
Migrations for 'learning_logs':
  learning_logs/migrations/0001_initial.py
    - Create model Topic
(ll_env)learning_log$

命令 makemigrations 让 Django 确定该如何修改数据库,使其能够存储与前面定义的新模型相关联的数据。输出表明 Django 创建了一个名为 0001_initial.py 的迁移文件,这个文件将在数据库中为模型 Topic 创建一个表。

下面应用这种迁移,让 Django 替我们修改数据库:

复制代码
(ll_env)learning_log$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, learning_logs, sessions
Running migrations:
  Applying learning_logs.0001_initial... OK

这个命令的大部分输出与首次执行命令 migrate 的输出相同。需要检查的是最后一行输出,其中 Django 指出在为 learning_logs 应用迁移时一切正常。

每当需要修改"学习笔记"管理的数据时,都采取如下三个步骤:修改 models.py,对 learning_logs 调用 makemigrations,以及让 Django 迁移项目。

连接数据库(这边使用的是SQLiteStudio)

模型中创建的类的属性对应的是数据库中的列名(字段)

整理总结前面步骤

1.创建虚拟环境(一个项目只创建一次即可)相当于重新安装了一个Python解释器

2.通过命令activate 激活虚拟环境(每次编写代码都需要激活,启动Django服务时也需要激活)

3.安装django库(pip install django只需要安装一次即可)

4.创建Django项目 startproject(只创建一次即可)

5.使用pycharm打开项目

6.创建应用 startapp(一个项目中可能创建多次)

7.在settings.py中安装项目(一个项目安装一次即可)installed_apps

8.在models.py中编写类,一个类对应数据库中一个表,类中的一个属性对应表中一个字段(列名)

9.迁移数据库,修改数据库 migrate ,makemigrations

10.启动django服务 python manage.py runserver

3 Django管理网站

Django 提供的管理网站(admin site)让你能够轻松地处理模型。Django 管理网站仅供网站的管理员使用,普通用户不能使用。本节将建立管理网站,并通过它使用模型 Topic 来添加一些主题。

3.1 创建超级用户

Django 允许创建具备所有权限的用户,即超级用户 (superuser)。权限决定了用户可执行的操作。最严格的权限设置只允许用户阅读网站的公开信息。注册用户通常可阅读自己的私有数据,还可查看一些只有会员才能查看的信息。为了有效地管理项目,网站所有者通常需要访问网站存储的所有信息。优秀的管理员会小心地对待用户的敏感信息,因为用户对其访问的应用程序有极大的信任。

要在 Django 中创建超级用户,请执行下面的命令并按提示做:

python 复制代码
(ll_env)learning_log$ python manage.py createsuperuser

① Username (leave blank to use 'eric'): ll_admin

② Email address:

③ Password:

Password (again):

Superuser created successfully.

(ll_env)learning_log$

在执行命令 createsuperuser 时,Django 会提示输入超级用户的用户名(见 ①)。这里输入的是 ll_admin,但其实可以输入任意用户名。既可输入电子邮箱地址,也可让这个字段为空(见 ②)。需要输入密码两次(见 ③)。

注意:可以对网站管理员隐藏一些敏感信息。例如,Django 并不存储你输入的密码,而存储从该密码派生出的一个字符串,称为哈希值。每当你输入密码时,Django 都会计算其哈希值,并将结果与存储的哈希值进行比较。如果这两个哈希值相同,你就通过了身份验证。这样,即便黑客获得了网站数据库的访问权,也只能获取其中存储的哈希值,无法获取密码。在网站配置正确的情况下,几乎无法根据哈希值推导出原始密码。

3.2 向管理网站注册模型

Django 自动在管理网站中添加了一些模型,如 User 和 Group,如果要添加我们创建的模型,则必须手动注册。

在我们创建应用程序 learning_logs 时,Django 在 models.py 所在的目录中创建了一个名为 admin.py 的文件:

admin.py

python 复制代码
from django.contrib import admin

在这里注册你的模型

为了向管理网站注册 Topic,请输入下面的代码:

复制代码
from django.contrib import admin

from .models import Topic

admin.site.register(Topic)

首先导入要注册的模型 Topic。models 前面的句点让 Django 在 admin.py 所在的目录中查找 models.py。admin.site.register() 让 Django 通过管理网站管理模型。

现在,使用超级用户账户访问管理网站:访问 http://localhost:8000/admin/,并输入刚创建的超级用户的用户名和密码。将看到类似于图 18-2 所示的屏幕,这个网页不仅让你能够添加和修改用户和用户组,还可以管理与刚才定义的模型 Topic 相关的数据。

Topics是在models.py中定义的类,注册之后会产生的。

图包含模型 Topic 的管理网站

注意:如果在浏览器中看到一条消息,指出访问的网页不可用,请确认在终端窗口中运行着 Django 服务器。如果没有,请激活虚拟环境,并执行命令 python manage.py runserver。在开发过程中,如果无法通过浏览器访问项目,首先应采取的故障排除措施是,先关闭所有打开的终端,再打开终端并执行命令 runserver。

3.3 添加主题

向管理网站注册 Topic 后,我们来添加第一个主题。为此,单击 Topics 进入主题网页,它几乎是空的,因为还没有添加任何主题。单击 Add Topic,会出现一个用于添加新主题的表单。在第一个方框中输入 Chess 并单击 Save,我们将回到主题管理页面,其中包含刚创建的主题。

下面再创建一个主题,以便有更多的数据可用。再次单击 Add Topic,并输入 Rock Climbing。单击 Save 后将回到主题管理页面,其中会包含主题 Chess 和 Rock Climbing。

4 定义模型 Entry

要记录学到的国际象棋和攀岩知识,用户必须能够在学习笔记中添加条目。因此,需要定义相关的模型。每个条目都与特定的主题相关联,这种关系称为多对一关系,即多个条目可关联到同一个主题。

下面是模型 Entry 的代码,请将这些代码放在文件 models.py 中:

models.py

python 复制代码
from django.db import models

class Topic(models.Model):
    --snip--

class Entry(models.Model): ①
    """学到的有关某个主题的具体知识"""
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE) ②
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    class Meta: ④
        verbose_name_plural = 'entries'

    def __str__(self):
        """返回一个表示条目的简单字符串"""
        return f"{self.text[:50]}..." ⑤

像 Topic 一样,Entry 也继承了 Django 基类 Model(见①)。第一个属性 topic 是个 ForeignKey 实例(见②)。外键(foreign key)是一个数据库术语,它指向数据库中的另一条记录,这里则是将每个条目关联到特定的主题。在创建每个主题时,都为其分配一个键(ID)。当需要在两项数据之间建立联系时,Django 就会使用与每项信息相关联的键。我们稍后将根据这些联系获取与特定主题相关联的所有条目。实参 on_delete=models.CASCADE 让 Django 在删除主题的同时删除所有与之相关联的条目,这称为级联删除(cascading delete)。

接下来是属性 text,它是一个 TextField 实例(见③)。这种字段的长度不受限制,因为我们不想限制条目的长度。属性 date_added 让我们能够按创建顺序呈现条目,并在每个条目旁边放置时间戳。

我们在 Entry 类中嵌套了 Meta 类(见④)。Meta 存储用于管理模型的额外信息。在这里,它让我们能够设置一个特殊属性,让 Django 在需要时使用 Entries 表示多个条目。如果没有这个类,Django 将使用 Entrys 表示多个条目。

str () 方法告诉 Django 在呈现条目时应显示哪些信息。条目包含的文本可能很长,因此让 str() 方法只返回 text 的前 50 个字符(见⑤)。这里还添加了一个省略号,指出显示的并非完整的条目。

5 迁移模型 Entry

添加新模型后,需要再次迁移数据库。你将慢慢地对这个过程了如指掌: 修改 models.py,执行命令 python manage.py makemigrations app_name ,再执行命令**python manage.py migrate**。

请使用如下命令迁移数据库并查看输出:

python 复制代码
(ll_env)learning_log$ python manage.py makemigrations learning_logs
Migrations for 'learning_logs':
  learning_logs/migrations/0002_entry.py
    - Create model Entry
(ll_env)learning_log$ python manage.py migrate
Operations to perform:
  --snip--
  Applying learning_logs.0002_entry... OK

生成了新的迁移文件 0002_entry.py,它告诉 Django 如何修改数据库,使其能够存储与模型 Entry 相关的信息(见①)。然后执行命令 migrate,我们发现 Django 应用了该迁移且一切正常(见②)。

Entry表中有4列,id列是自动产生的主键列,剩下三列是我们在类当中建的实例属性。

6 向管理网站注册 Entry

我们还需要注册模型 Entry,为此要将 admin.py 修改成类似于下面这样:

admin.py

python 复制代码
from django.contrib import admin
from .models import Topic, Entry

admin.site.register(Topic)
admin.site.register(Entry)

Topics是主键,Entries是外键,是一对多关系。

返回 http://localhost/admin/,将看到 Learning_Logs 下列出了 Entries。单击 EntriesAdd 链接,或者单击 Entries 再选择 Add entry,将看到一个下拉列表,让我们选择要为哪个主题创建条目,还有一个用于输入条目的文本框。从下拉列表中选择 Chess,并添加一个条目。下面是我添加的第一个条目:

The opening is the first part of the game, roughly the first ten moves or so. In the opening, it's a good idea to do three things--- bring out your bishops and knights, try to control the center of the board, and castle your king.(国际象棋的第一个阶段是开局,大概是前10步左右。在开局阶段,最好做三件事情:将象和马调出来,努力控制棋盘的中间区域,以及用车将王护住。) Of course, these are just guidelines. It will be important to learn when to follow these guidelines and when to disregard these suggestions.(当然,这些只是指导原则。学习在什么情况下遵守、在什么情况下不用遵守这些原则很重要。)

当单击 Save 时,将返回主条目管理页面。在这里,可以发现使用 `text:50` 作为条目的字符串表示的好处:管理界面只显示了条目的开头部分而不是所有文本,这使得管理多个条目容易得多。 再来创建一个国际象棋条目,并创建一个攀岩条目,以提供一些初始数据。下面是第二个国际象棋条目:

In the opening phase of the game, it's important to bring out your bishops and knights. These pieces are powerful and maneuverable enough to play a significant role in the beginning moves of a game.(在国际象棋的开局阶段,将象和马调出来很重要。这些棋子威力大、机动性强,在开局阶段扮演着重要的角色。)

下面是第一个攀岩条目:

One of the most important concepts in climbing is to keep your weight on your feet as much as possible. There's a myth that climbers can hang all day on their arms. In reality, good climbers have practiced specific ways of keeping their weight over their feet whenever possible.(最重要的攀岩概念之一是,尽可能让双脚承受体重。有人误认为攀岩者能依靠手臂的力量坚持攀岩一整天。实际上,优秀的攀岩者都经过专门训练,能够尽可能让双脚承受体重。)

接着开发"学习笔记"时,这三个条目提供了可用的数据。

7 Django shell

输入一些数据后,就可以通过交互式终端会话以编程的方式查看这些数据了。这种交互式环境称为 Django shell,是测试项目和排除故障的理想之地。下面是一个交互式 shell 会话的示例:

python 复制代码
(ll_env)learning_log$ python manage.py shell
>>> from learning_logs.models import Topic
>>> Topic.objects.all()
<QuerySet [<Topic: Chess>, <Topic: Rock Climbing>]>

在活动的虚拟环境中执行时,命令 python manage.py shell 会启动 Python 解释器,让你能够探索存储在项目数据库中的数据。这里先导入模块 learning_logs.models 中的模型 Topic(见①),再使用 Topic.objects.all() 方法获取模型 Topic 的所有实例,这将返回一个称为 ** 查询集(queryset)** 的列表。

<QuerySet \, \> 的意思是Topic的所有对象。

可以像遍历列表一样遍历查询集。下面演示了如何查看分配给每个主题对象的 ID:

python 复制代码
>>> topics = Topic.objects.all()
>>> for topic in topics:
...     print(topic.id, topic)
...
1 Chess
2 Rock Climbing

将返回的查询集赋给 topics,再打印每个主题的 id 属性和字符串表示。从输出可知,主题 Chess 的 ID 为 1,而 Rock Climbing 的 ID 为 2。

知道主题对象的 ID 后,就可以使用 Topic.objects.get() 方法获取该对象并查看其属性了。下面来看看主题 Chess 的属性 textdate_added 的值:

python 复制代码
>>> t = Topic.objects.get(id=1)
>>> t.text
'Chess'
>>> t.date_added
datetime.datetime(2022, 5, 20, 3, 33, 36, 928759,
    tzinfo=datetime.timezone.utc)

还可以查看与主题相关联的条目。前面给模型 Entry 定义了属性 topic。这是一个 ForeignKey,将条目与主题关联起来。利用这种关联,Django 能够获取与特定主题相关联的所有条目,如下所示:

python 复制代码
>>> t.entry_set.all()
<QuerySet [<Entry: The opening is the first part of the game, roughly...>, <Entry:
In the opening phase of the game, it's important t...>]>

要通过外键关系获取数据,可使用相关模型的小写名称、下划线和单词 `set`(见①)。假设有模型 `Pizza` 和 `Topping`,而 `Topping` 通过一个外键关联到 `Pizza`。如果有一个名为 `my_pizza` 的 `Pizza` 对象,就可以使用代码 `my_pizza.topping_set.all()` 来获取这张比萨的所有配料。

稍后在编写用户可请求的网页时,将使用这种语法。要确认代码能否获取所需的数据时,shell 很有帮助。如果代码在 shell 中的行为符合预期,那么它们在项目文件中也能正常工作。如果代码引发了错误或者获取的数据不符合预期,那么在简单的 shell 环境中排除故障要比在生成网页的文件中排除故障容易得多。我们不会太多地使用 shell,但应继续使用它来熟悉对存储在项目中的数据进行访问的 Django 语法。

每次修改模型后,都需要重启 shell,以便看到修改的效果。要退出 shell 会话,可按 Ctrl + D。如果你使用的是 Windows 系统,应先按 Ctrl + Z,再按回车键。

动手试一试练习:简短的条目** 当前,当 Django 在管理网站或 shell 中显示 `Entry` 实例时,模型 `Entry` 的 `str()` 方法都在其末尾加上省略号。请在 `str()` 方法中添加一条 `if` 语句,仅在条目长度超过 50 个字符时才添加省略号。使用管理网站添加一个不超过 50 个字符的条目,并核实在显示它时不带省略号。

相关推荐
闵孚龙1 小时前
《PyTorch 深度修炼》优化器:参数到底是怎么被更新的
人工智能·pytorch·python
码云骑士1 小时前
27-Docker部署Django(上)-从2GB到180MB的镜像瘦身实战
docker·容器·django
子豪-中国机器人1 小时前
Python 阶段性综合强化训练(新版)
开发语言·python·语音识别
杰杰7981 小时前
DRF的分页讲解-入门篇 三个基础分页类介绍
python·django
摇滚侠1 小时前
SSM 框架实战教程 SpringBoot 自动配置 176-179
java·spring boot·后端
ywl4708120871 小时前
spring单列bean之循环依赖核心源码解读
java·后端·spring
苏三说技术1 小时前
推荐一个牛逼的企业知识库系统
后端
清水白石0081 小时前
让对象像函数一样工作:深入理解 Python `__call__` 的作用与实战场景
开发语言·python
大刚测试开发实战1 小时前
TestHub数据工厂发布!附更新指南
前端·后端·github