说明:这篇文章只是记录自己自学本书的一个痕迹,日后来看作为一个念想。至于做为公开,是希望对一些同样跟我一样的朋友有一点点帮助,当然我本人就是小白,帮助可能也不大哈哈。
这篇文章记录了《python编程从入门到实践》的第18章的自测项目,因为这本书的版本比较老,而Django又更新很快,所以自测起来有很多坑,总之面临许多问题,最终通过查找许多文章和请教大佬才得以完成,所以希望对大家伙有点参考的价值哦。谢谢大家啦。

目录

18.1 建立项目

18.1.1 制定规范

18.1.2 建立虚拟环境

18.1.3 安装 virtualenv

18.1.4 激活虚拟环境

18.1.5 安装Django

18.1.6 在Django中创建项目

18.1.7 创建数据库

18.1.8 查看项目

18.2 创建应用程序

18.2.1 定义模型

18.2.2 激活模型

18.2.3 Django管理网站

1. 创建超级用户

2. 向管理网站注册模型

3. 添加主题

18.2.4 定义模型Entry

18.2.5 迁移模型 Entry

18.2.6 向管理网站注册 Entry

18.2.7 Django shell

18.3 创建网页:学习笔记主页

18.3.1 映射URL

18.3.2 编写视图

18.3.3 编写模板

18.4 创建其他网页

18.4.1 模板继承

1. 父模板

2. 子模板

18.4.2 显示所有主题的页面

1. URL模式

2. 视图

3. 模板

18.4.3 显示特定主题的页面

1. URL模式

2. 视图

3. 模板

4. 将显示所有主题的页面中的每个主题都设置为链接

18.5 小结


18.1 建立项目

我们在建立项目时,需要以规范的方式对项目进行描述,再建立虚拟环境,这非常重要,以便在其中创建项目。

18.1.1 制定规范

完整的规范详细说明了项目的目标,阐述了项目的功能,并讨论了项目的外观和用户界面。与任何良好的项目规划和商业计划书一样,规范应突出重点,帮助避免项目偏离轨道。这里不会制定完整的项目规划,而只列出一些明确的目标,以突出开发的重点。
 我们制定的规范如下:
  1. 我们要编写一个名为“学习笔记”的Web应用程序,让用户能够记录感兴趣的主题,并在学习每个主题的过程中添加日志条目。
  2. “学习笔记”的主页对这个网站进行描述, 并邀请用户注册或登录。
  3. 用户登录后,就可创建新主题、添加新条目以及阅读既有的条目。
  4. 学习新的主题时,记录学到的知识可帮助跟踪和复习这些知识。
优秀的应用程序让这个记录过程简单易行。

        18.1.2 建立虚拟环境

要使用Django,首先需要建立一个虚拟工作环境。
虚拟环境 是系统的一个位置,你可以在其中安装包,并将其与其他Python包隔离。将项目的库与其他项目分离是有益的,且为了在第20章将“学习笔记”部署到服务器,这也是必须的。
为项目新建一个目录,将其命名为learning_log,再在终端中切换到这个目录,并创建一个虚拟环境。
如果你使用的是Python 3,可使用如下命令来创建虚拟环境:
learning_log$ python -m venv ll_env
learning_log$

这里运行了模块venv ,并使用它来创建一个名为ll_env的虚拟环境。如果这样做管用,请跳到后面的18.1.4节;如果不管用,请阅读18.1.3节。

        18.1.3 安装 virtualenv

如果你使用的是较早的Python版本,或者系统没有正确地设置,不能使用模块venv ,可安装virtualenv包。为此,可执行如下命令:
$ pip install --user virtualenv
别忘了,对于这个命令,你可能需要使用稍微不同的版本
(如果你没有使用过pip,请参阅12.2.1节)。
注意:
如果你使用的是Linux系统,且上面的做法不管用,可使用系统的包管理器来安装virtualenv。例如,要在Ubuntu系统中安装virtualenv,可使用命令sudo apt- get install python-virtualenv 。
在终端中切换到目录learning_log,并像下面这样创建一个虚拟环境:
learning_log$ virtualenv ll_env
New python executable in ll_env/bin/python
Installing setuptools, pip...done.
learning_log$
注意:
如果你的系统安装了多个Python版本,需要指定virtualenv使用的版本。例如,命令virtualenv ll_env --python=python3 创建一个使用Python 3的虚拟
环境。

        18.1.4 激活虚拟环境

建立虚拟环境后,需要使用下面的命令激活它:
learning_log$ ll_env\Scripts\activate
❶ (ll_env)learning_log$
这个命令运行ll_env/bin中的脚本activate。环境处于活动状态时,环境名将包含在括号内,如❶处所示。在这种情况下,你可以在环境中安装包,并使用已安装的包。你在ll_env中安装的包仅在该环境处于活动状态时才可用。
注意
如果你使用的不是Windows系统,请使用命令source ll_env/bin/activate 来激活这个虚拟环境。

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

(ll_env)learning_log$ deactivate
learning_log$

如果关闭运行虚拟环境的终端,虚拟环境也将不再处于活动状态。

        18.1.5 安装Django

创建并激活虚拟环境后,就可安装Django了:
 (ll_env)learning_log$ pip install Django
Installing collected packages: Django
Successfully installed Django
Cleaning up...
(ll_env)learning_log$
 别忘了,Django仅在虚拟环境处于活动状态时才可用。
注:如果pip版本过低,请使用python.exe -m pip install --upgrade pip  先在虚拟环境pip更新
然后再安装Django。

        18.1.6Django中创建项目

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

❶(ll_env)learning_log$ django-admin startproject learning_log .❷ (ll_env)learning_log$ dirlearning_log ll_env manage.py ❸ (ll_env)learning_log$ dir learning_log ...asgi.py...__init__.py ...settings.py ... urls.py ...  wsgi.py
❶处的命令让Django新建一个名为learning_log的项目。这个命令末尾的句点让新项目使用合适的目录结构,这样开发完成后可轻松地将应用程序部署到服务器。
注意:
千万别忘了这个句点,否则部署应用程序时将遭遇一些配置问题。如果忘记了这个句点,就将创建的文件和文件夹删除(ll_env除外),再重新运行这个命令。
在❸处,运行了命令dir (在其它系统上为ls ),结果表明Django新建了一个名为learning_log的目录。它还创建了一个名为manage.py的文件,这是一个简单的程序,它接受
命令并将其交给Django的相关部分去运行。我们将使用这些命令来管理诸如使用数据库和运行服务器等任务。

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

        18.1.7 创建数据库

Django将大部分与项目相关的信息都存储在数据库中,因此我们需要创建一个供Django使用的数据库。为给项目“学习笔记”创建数据库,请在处于活动虚拟环境中的情况下执行下 面的命令:
(ll_env)learning_log$ python manage.py migrate
❶ Operations to perform:
Synchronize unmigrated apps: messages, staticfiles
Apply all migrations: contenttypes, sessions, auth, admin
--snip--
Applying sessions.0001_initial... OK(ll_env)learning_log$ dir
db.sqlite3 learning_log ll_env manage.py
我们将修改数据库称为迁移数据库。首次执行命令migrate 时,将让Django确保数据库与项目的当前状态匹配。在使用SQLite(后面将更详细地介绍)的新项目中首次执行这个 命令时,Django将新建一个数据库。在❶处,Django指出它将创建必要的数据库表,用于存储我们将在这个项目(Synchronize unmigrated apps,同步未迁移的应用程序 同 )中使用的 信息,再确保数据库结构与当前代码(Apply allmigrations,应用所有的迁移 应 )匹配。
在❷处,我们运行了命令dir ,其输出表明Django又创建了一个文件——db.sqlite3。SQLite是一种使用单个文件的数据库,是编写简单应用程序的理想选择,因为它让你不用太关注数据库管理的问题。

        18.1.8 查看项目

下面来核实Django是否正确地创建了项目。为此,可执行命令runserver ,如下所示:
(ll_env)learning_log$ python manage.py runserver
Performing system checks...
❶System check identified no issues (0 silenced).
October 16, 2022 - 13:10:38
❷Django version 4.1.2, using settings 'learning_log.settings'
❸Starting development server at http://127.0.0.1:8000/Quit the server with CTRL-BREAK.
Django启动一个服务器,让你能够查看系统中的项目,了解它们的工作情况。当你在浏览器中输入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创建的,让你知道
到目前为止一切正常。现在暂时不要关闭这个服务器。若要关闭这个服务器,按Ctrl+ C即可。

图18-1  到目前为止一切正常
如果出现错误消息“That port isalready in use”(指定端口已被占用),请执行命令
python manage.py runserver 8001 ,让Diango使用另一个端口;如果 这个端口也不可用,请不断执行上述命令,并逐渐增大其中的端口号,直到找到可用的端口。

18.2 创建应用程序

Django项目由一系列应用程序组成,它们协同工作,让项目成为一个整体。我们暂时只创建一个应用程序,它将完成项目的大部分工作。在第19章,我们将再添加一个管理用户账户的应用程序。
当前,在前面打开的终端窗口中应该还运行着runserver 。请再打开一个终端窗口(或标签页),并切换到manage.py所在的目录。激活该虚拟环境,再执行命令startapp :
 learning_log$ ll_env\Scripts\activate
(ll_env)learning_log$ python manage.py startapp learning_logs❶ (ll_env)learning_log$ dirdb.sqlite3 learning_log learning_logs ll_env manage.py
❷ (ll_env)learning_log$ dir learning_logs/admin.py apps.py__init__.py migrationsmodels.py tests.py views.py
命令startapp appname 让Django建立创建应用程序所需的基础设施。如果现在查看项目目录,将看到其中新增了一个文件夹learning_logs(见❶)。打开这个文件夹,看看 Django都创建了什么(见❷)。其中最重要的文件是models.py、admin.py和views.py。我们将使用models.py来定义我们要在应用程序中管理的数据。admin.py和views.py将在稍后介绍。

        18.2.1 定义模型

我们来想想涉及的数据。每位用户都需要在学习笔记中创建很多主题。用户输入的每个条目都与特定主题相关联,这些条目将以文本的方式显示。我们还需要存储每个条目的时间戳,以便能够告诉用户各个条目都是什么时候创建的。
打开文件models.py,看看它当前包含哪些内容:
models.py
from django.db import models# Create your models here.

这为我们导入了模块models,还让我们创建自己的模型。模型告诉Django如何处理应用程序中存储的数据。在代码层面,模型就是一个类,就像前面讨论的每个类一样,包含属性 和方法。下面是表示用户将要存储的主题的模型:
from django.db import models# 在这里创建模型
# Model--在Django中一个定义了模型基本功能的类
class Topic(models.Model):"""用户学习的主题"""text = models.CharField(max_length=200)               # CharField字符数据date_added = models.DateTimeField(auto_now_add=True)    # DateTimeField时间数据,# 参数auto_now_add=True,每当用户创建新主题时,这个属性自动设置为当前日期和时间# 告诉Django,默认使用哪个属性显示有关主题的信息。# __str__()显示模型的简单表示def __str__(self):"""返回模型的字符串表示"""return self.text
注意
要获悉可在模型中使用的各种字段,请参阅Django ModelField Reference(Django模型字段参考),其网址为https://docs.djangoproject.com/en/1.8/ref/models/fields/ 。 就当前而言,你无需全面了解其中的所有内容,但自己开发应用程序时,这些内容会提供极大的帮助。

        18.2.2 激活模型

要使用模型,必须让Django将应用程序包含到项目中。为此,打开settings.py(它位于目录learning_log/learning_log中),你将看到一个这样的片段,即告诉Django哪些应用程序安装
在项目中:
settings.py
--snip--
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages', 'django.contrib.staticfiles',)
--snip--
这是一个元组,告诉Django项目是由哪些应用程序组成的。请将INSTALLED_APPS 修改成下面这样,将前面的应用程序添加到这个元组中:
INSTALLED_APPS = ["django.contrib.admin","django.contrib.auth","django.contrib.contenttypes","django.contrib.sessions","django.contrib.messages","django.contrib.staticfiles",# 我的应用程序"learning_logs",
]
通过将应用程序编组,在项目不断增大,包含更多的应用程序时,有助于对应用程序进行跟踪。这里新建了一个名为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 应用迁移时一切正常(OK )。
每当需要修改“学习笔记”管理的数据时,都采取如下三个步骤:修改models.py;对learning_logs 调用makemigrations ;让Django迁移项目。

18.2.3 Django管理网站

为应用程序定义模型时,Django提供的管理网站(admin site)让你能够轻松地处理模型。网站的管理员可使用管理网站,但普通用户不能使用。在本节中,我们将建立管理网站, 并通过它使用模型Topic 来添加一些主题。

1. 创建超级用户

Django允许你创建具备所有权限的用户——超级用户。权限决定了用户可执行的操作。最严格的权限设置只允许用户阅读网站的公开信息;注册了的用户通常可阅读自己的私有数据,还可查看一些只有会员才能查看的信息。为有效地管理Web应用程序,网站所有者通常需要访问网站存储的所有信息。优秀的管理员会小心对待用户的敏感信息,因为用户对其访问的应用程序有极大的信任。
为在Django中创建超级用户,请执行下面的命令并按提示做:
(ll_env)learning_log$ python manage.py createsuperuser
❶ Username (leave blank to use 'ehmatthes'): ll_admin
❷ Email address:
❸ Password:Password (again):Superuser created successfully.
(ll_env)learning_log$
你执行命令createsuperuser 时,Django提示你输入超级用户的用户名(见❶)。这里我们输入的是ll_admin,但你可以输入任何用户名,比如电子邮件地址,也可让这个字段为空(见❷)。你需要输入密码两次(见❸)。
        注 可能会对网站管理员隐藏有些敏感信息。例如,Django并不存储你输入的密码,而存储从该密码派生出来的一个字符串——散列值。每当你输入密码时,Django都计算其散列值,并将结果与存储的散列值进行比较。如果这两个散列值相同,就通过了身份验证。通过存储散列值,即便黑客获得了网站数据库的访问权,也只能获取其中存储的散列值,而无法获得密码。在网站配置正确的情况下,几乎无法根据散列值推导出原始密码。

2. 向管理网站注册模型

Django自动在管理网站中添加了一些模型,如User 和Group ,但对于我们创建的模型,必须手工进行注册。
我们创建应用程序learning_logs 时,Django在models.py所在的目录中创建了一个名为admin.py的文件:

admin.py
from django.contrib import admin# Register your models here.
为向管理网站注册Topic ,请输入下面的代码:
from django.contrib import admin#  向管理网站注册Topic模型
from learning_logs.models import Topic#这些代码导入我们要注册的模型Topic,再使用admin.site.register()admin.site.register(Topic)
#让Django通过管理网站管理我们的模型。
现在,使用超级用户账户访问管理网站:访问http://localhost:8000/admin/ ,并输入你刚创建的超级用户的用户名和密码,你将看到类似于图18-2所示的屏幕。这个网页让你能够添加 和修改用户和用户组,还可以管理与刚才定义的模型Topic 相关的数据。

图18-2 包含模型 Topic 的管理网站

3. 添加主题

向管理网站注册Topic 后,我们来添加第一个主题。
为此,单击Topics进入主题网页,它几乎是空的,这是因为我们还没有添加任何主题。单击Add,你将看到一个用于添加新主 题的表单。在第一个方框中输入Chess ,再单击Save,这将返回到主题管理页面,其中包含刚创建的主题。
下面再创建一个主题,以便有更多的数据可供使用。再次单击Add,并创建另一个主题Rock Climbing 。当你单击Save时,将重新回到主题管理页面,其中包含主题Chess和Rock Climbing。

18.2.4 定义模型Entry

要记录学到的国际象棋和攀岩知识,需要为用户可在学习笔记中添加的条目定义模型。每个条目都与特定主题相关联,这种关系被称为多对一关系,即多个条目可关联到同一个
主题。
下面是模型Entry 的代码:
models.py
from django.db import models# 在这里创建模型
# Model--在Django中一个定义了模型基本功能的类
class Topic(models.Model):--snip--class Entry(models.Model):"""学到的有关某个主题的具体知识"""# 需要在两项数据之间建立联系时,Django使用与每项信息相关联的键。topic = models.ForeignKey(Topic, on_delete=models.CASCADE)text = models.TextField()date_added = models.DateTimeField(auto_now_add=True)# Meta存储用于管理模型的额外信息。设置一个特殊属性,Entries来表示多个条目。# 若无这个类,用Entrys表示多个条目class Meta:verbose_name_plural = 'entries'def __str__(self):"""返回模型的字符串表示"""return self.text[:50] + "..."
  • 像Topic 一样,Entry 也继承了Django基类Model 。
  • 第一个属性topic 是一个ForeignKey 实例。外键是一个数据库术语,它引用了数据库中的另一条记录;这些代码将每个条目关联到特定的主题。每个主题创建时,都给它分配了一个键(或ID)。需要在两项数据之间建立联系时,Django使用与每项信息相关联的键。稍后我们将根据这些联系获取与特定主题相关联的所有条目。
  • 接下来是属性text ,它是一个TextField 实例。这种字段不需要长度限制,因为我们不想限制条目的长度。
  • 属性date_added 让我们能够按创建顺序呈现条目,并在每个条目旁边放置时间戳。
  • 我们在Entry 类中嵌套了Meta 类。Meta 存储用于管理模型的额外信息,在这里,它让我们能够设置一个特殊属性,让Django在需要时使用Entries 来表示多个条目。如果没有这个类, Django将使用Entrys来表示多个条目。
  • 最后,方法__str__() 告诉Django,呈现条目时应显示哪些信息。由于条目包含的文本可能很长,我们让Django只显示text 的前50个字符(见❺)。我们还添加了一个省略号,指出显示的并非整个条目。

18.2.5 迁移模型 Entry

由于我们添加了一个新模型,因此需要再次迁移数据库。你将慢慢地对这个过程了如指掌:修改models.py,执行命令python manage.py makemigrations app_name
再执行命令python manage.py migrate 。
下面来迁移数据库并查看输出:
(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:
   Apply all migrations: admin, auth, contenttypes, learning_logs, sessions
    Running migrations:
   ❷       Applying learning_logs.0002_entry... OK
(ll_env)learning_log$

生成了一个新的迁移文件——0002_entry.py,它告诉Django如何修改数据库,使其能够存储与模型Entry 相关的信息(见❶)。执行命令migrate ,我们发现Django应用了这种迁移且一切顺利(见❷)。

18.2.6 向管理网站注册 Entry

我们还需要注册模型Entry 。为此,需要将admin.py修改成类似于下面这样:
admin.py
from django.contrib import admin#  向管理网站注册Topic模型
from learning_logs.models import Topic, Entryadmin.site.register(Topic)
admin.site.register(Entry)
返回到http://localhost/admin/ ,你将看到learning_logs下列出了Entries。单击Entries的Add链接,或者单击Entries再选择Add entry。你将看到一个下拉列表,让你能够选择要为哪个主题创建条目,还有一个用于输入条目的文本框。从下拉列表中选择Chess,并添加一个条目。
下面是我添加的国际象棋的第一个条目
  • The opening is thefirst part ofthe game, roughly thefirst tenmoves or so. In the opening, it'sa good ideato do threethings— bring out your bishopsand knights, try to controlthecenter ofthe board,and castle your king.(国际象棋的第一个阶段是开局,大致是前10步左右。在开局阶段,最好做三件事情:将象和马调出来;努力控制棋盘的中间区域;用车将王护住。)
  • Ofcourse, thesearejust guidelines. It will beimportant to learnwhen to followthese guidelinesand when to disregard thesesuggestions.(当然,这些只是指导原则。学习什么情况下遵守这些原则、什么情况下不用遵守很重要。)
下面是第二个国际象棋条目
  • In the opening phase ofthe game, it's important to bring out your bishopsand knights. These piecesare powerfuland maneuverableenough to play asignificant rolein the beginningmoves ofa game.(在国际象棋的开局阶段,将象和马调出来很重要。这些棋子威力大,机动性强,在开局阶段扮演着重要角色。)
下面是第一个攀岩条目:
  • One ofthe most importantconcepts in climbing is to keep your weight on your feetas much as possible. There'sa myth thatclimberscan hang all day on theirarms. In reality, good climbers have practiced specific ways of keeping their weight over their feet whenever possible.(最重要的攀岩概念之一是尽可能让双脚承受体重。有谬误认为攀岩者能依靠手臂的力量坚持一整天。实际上,优秀的攀岩者都经过专门训练,能够尽可能让双脚承受体重。)

当你单击Save时,将返回到主条目管理页面。在这里,你将发现使用text[:50] 作为条目的字符串表示的好处:管理界面中,只显示了条目的开头部分而不是其所有文本,这使得管理多个条目容易得多。

继续往下开发“学习笔记”时,这三个条目可为我们提供使用的数据。

18.2.7 Django shell

输入一些数据后,就可通过交互式终端会话以编程方式查看这些数据了。这种交互式环境称为Django shell,是测试项目和排除其故障的理想之地。下面是一个交互式shell会话
示 例:
(ll_env)learning_log$ python manage.py shell
❶ >>> from learning_logs.models import Topic
>>> Topic.objects.all()
[<Topic: Chess>, <Topic: Rock Climbing>]

在活动的虚拟环境中执行时,命令python manage.py shell 启动一个Python解释器,可使用它来探索存储在项目数据库中的数据。在这里,我们导入了模块learning_logs.models 中的模型Topic (见❶),然后使用方法Topic.objects.all() 来获取模型Topic 的所有实例;它返回的是一个列表,称为查询集 (queryset)。

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

>>> 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后,就可获取该对象并查看其任何属性。下面来看看主题Chess的属性text 和date_added 的值:
>>> t = Topic.objects.get(id=1)
>>> t.text
'Chess'
>>> t.date_added
datetime.datetime(2015, 5, 28, 4, 39, 11, 989446, tzinfo=<UTC>)

我们还可以查看与主题相关联的条目。前面我们给模型Entry 定义了属性topic ,这是一个ForeignKey ,将条目与主题关联起来。利用这种关联,Django能够获取与特定主题相关联的所有条目,如下所示:
❶ >>> t.entry_set.all()
[<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 的对象,表示一张比萨,就可使用代码my_pizza.topping_set.all() 来获取这张比萨的所有配料。
  • 编写用户可请求的网页时,我们将使用这种语法。确认代码能获取所需的数据时,shell很有帮助。如果代码在shell中的行为符合预期,那么它们在项目文件中也能正确地工作。
  • 如果代码引发了错误或获取的数据不符合预期,那么在简单的shell环境中排除故障要比在生成网页的文件中排除故障容易得多。
  • 我们不会太多地使用shell,但应继续使用它来熟悉对存储在项目中的数据进行访问的Django语法。
注:
每次修改模型后,你都需要重启shell,这样才能看到修改的效果。要退出shell会话,可按Ctr + D;如果你使用的是Windows系统,应按Ctr + Z,再按回车键。

18.3 创建网页:学习笔记主页

  • 使用Django创建网页的过程通常分三个阶段:定义URL、编写视图和编写模板。首先,你必须定义URL模式。URL模式描述了URL是如何设计的,让Django知道如何将浏览器请求与网站URL匹配,以确定返回哪个网页。
  • 每个URL都被映射到特定的视图视 ——视图函数获取并处理网页所需的数据。视图函数通常调用一个模板,后者生成浏览器能够理解的网页。为明白其中的工作原理,我们来创建学习笔记的主页。我们将定义该主页的URL、编写其视图函数并创建一个简单的模板。
  • 鉴于我们只是要确保“学习笔记”按要求的那样工作,我们将暂时让这个网页尽可能简单。Web应用程序能够正常运行后,设置样式可使其更有趣,但中看不中用的应用程序毫无意义。就目前而言,主页只显示标题和简单的描述。

        18.3.1 映射URL

用户通过在浏览器中输入URL以及单击链接来请求网页,因此我们需要确定项目需要哪些URL。主页的URL最重要,它是用户用来访问项目的基础URL。当前,基础URL(http://localhost:8000/)返回默认的Django网站,让我们知道正确地建立了项目。我们将修改这一点,将这个基础URL映射到“学习笔记”的主页。
打开项目主文件夹learning_log中的文件urls.py,你将看到如下代码:
urls.py
from django.contrib import admin
from django.urls import pathurlpatterns = [path("admin/", admin.site.urls),
]
前两行导入了为项目和管理网站管理URL的函数和模块。
这个文件的主体定义了变量urlpatterns 。
在这个针对整个项目的urls.py文件中,变量urlpatterns 包含项目中的应用程序的URL。
admin.site.urls 模块定义了可在管理网站中请求的所有URL。

而我们需要包含learning_logs的URL:

# 导入为项目和管理网站管理URL的函数和模块
from django.urls import include, path
from django.contrib import admin# urlpatterns包含项目中的应用程序的URL
urlpatterns = [# admin.site.urls定义了在管理网站中请求的所有URLpath('admin/',admin.site.urls),# 指向learning_logs.urls模块,namespace让learning_logs的URL与项目中的其他URL区分path('', include(('learning_logs.urls','learning_logs'), namespace='learning_logs')),]

 默认的urls.py包含在文件夹learning_log中,现在我们需要在文件夹learning_logs中创建另一个urls.py文件:

urls.py
"""定义learning_logs的URL模式"""
from django.urls import path# 从当前的urls.py所在文件夹导入views
from . import views
app_name = 'learning_logs'# 包含可在应用程序learning_ logs中请求的网页
urlpatterns = [# 主页path('', views.index, name='index'),
]
  • 为弄清楚当前位于哪个urls.py文件中,我们在这个文件开头添加了一个文档字符串。
  • 接下来,我们导入了函数url ,因为我们需要使用它来将URL映射到视图,我们还导入了模块views ,其中的句点让Python从当前的urls.py模块所在的文件夹中导入视图。
  • 在这个模块中,变量urlpatterns 是一个列表,包含可在应用程序learning_logs 中请求的网页。
  • 实际的URL模式是一个对函数url() 的调用,这个函数接受三个实参。第一个是一个正则表达式。Django在urlpatterns 中查找与请求的URL字符串匹配的正则表达式,因此正则表达式定义了Django可查找的模式。
  • 总体而言,这个正则表达式让Python查找开头和末尾之间没有任何东西的URL。Python忽略项目的基础URL(http://localhost:8000/),因此这个正则表达式与基础URL匹配。其他URL都与这个正则表达式不匹配。如果请求的URL不与任何URL模式匹配Django将返回一个错误页面。
  • url() 的第二个实参指定了要调用的视图函数。请求的URL与前述正则表达式匹配时,Django将调用views.index (这个视图函数将在下一节编写)。第三个实参将这个URL模式的名称指定为index,让我们能够在代码的其他地方引用它。每当需要提供到这个主页的链接时,我们都将使用这个名称,而不编写URL。

正则表达式通常被称为regex,几乎每种编程语言都使用它。它们的用途多得难以置信,但需要经过一定的练习才能熟悉。如果你不明白前面介绍的内容,也不用担心,你在完成这个项目的过程中,将会看到很多正则表达式。

        18.3.2 编写视图

视图函数接受请求中的信息,准备好生成网页所需的数据,再将这些数据发送给浏览器——这通常是使用定义了网页是什么样的模板实现的。
learning_logs中的文件views.py是你执行命令python manage.py startapp 时自动生成的,当前其内容如下:
views.py
from django.shortcuts import render# Create your views here.
当前,这个文件只导入了函数render() ,它根据视图提供的数据渲染响应。下面的代码演示了该如何为主页编写视图:
from django.shortcuts import render# Create your views here.
def index(request):return render(request,'learning_logs/index.html')
URL请求与我们刚才定义的模式匹配时,Django将在文件views.py中查找函数index() ,再将请求对象传递给这个视图函数。在这里,我们不需要处理任何数据,因此这个函数只包含调用render() 的代码。这里向函数render() 提供了两个实参:原始请求对象以及一个可用于创建网页的模板。下面来编写这个模板。

        18.3.3 编写模板

模板定义了网页的结构。模板指定了网页是什么样的,而每当网页被请求时,Django将填入相关的数据。
模板让你能够访问视图提供的任何数据。我们的主页视图没有提供任何数据,因此相应的模板非常简单。
在文件夹learning_logs中新建一个文件夹,并将其命名为templates。在文件夹templates中,再新建一个文件夹,并将其命名为learning_logs。这好像有点多余(我们在文件夹learning_logs中创建了文件夹templates,又在这个文件夹中创建了文件夹learning_logs),但建立了Django能够明确解读的结构,即便项目很大,包含很多应用程序亦如此。
在最里面的文件夹learning_logs中,新建一个文件,并将其命名为index.html,再在这个文件中编写如下代码:
index.html
<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>
这个文件非常简单。对于不熟悉HTML的读者,这里解释一下:标签<p></p> 标识段落;标签<p> 指出了段落的开头位置,而标签</p> 指出了段落的结束位置。这里定义了两个段落:第一个充当标题,第二个阐述了用户可使用“学习笔记”来做什么。
现在,如果你请求这个项目的基础URL——http://localhost:8000/,将看到刚才创建的网页,而不是默认的Django网页。Django接受请求的URL,发现该URL与模式r'^$' 匹配,因此调用函数views.index() ,这将使用index.html包含的模板来渲染网页,结果如图18-3所示。

创建网页的过程看起来可能很复杂,但将URL、视图和模板分离的效果实际上很好。这让我们能够分别考虑项目的不同方面,且在项目很大时,让各个参与者可专注于其最擅长的方面。
例如,
数据库专家可专注于模型,程序员可专注于视图代码,而Web设计人员可专注于模板。

18.4 创建其他网页

制定创建网页的流程后,可以开始扩充“学习笔记”项目了。我们将创建两个显示数据的网页,其中一个列出所有的主题,另一个显示特定主题的所有条目。对于每个网页,我们都将指定URL模式,编写一个视图函数,并编写一个模板。但这样做之前,我们先创建一个父模板,项目中的其他模板都将继承它。

        18.4.1 模板继承

创建网站时,几乎都有一些所有网页都将包含的元素。在这种情况下,可编写一个包含通用元素的父模板,并让每个网页都继承这个模板,而不必在每个网页中重复定义这些通用元素。这种方法能让你专注于开发每个网页的独特方面,还能让修改项目的整体外观容易得多。

1. 父模板

我们首先来创建一个名为base.html的模板,并将其存储在index.html所在的目录中。这个文件包含所有页面都有的元素;其他的模板都继承base.html。当前,所有页面都包含的元素只有顶端的标题。我们将在每个页面中包含这个模板,因此我们将这个标题设置为到主页的链接:
base.html
<p><a href="{% url 'learning_logs:index' %}">Learning Log</a>
</p>
{% block content %}{% endblock content %}
  • 这个文件的第一部分创建一个包含项目名的段落,该段落也是一个到主页的链接。
  • 为创建链接,我们使用了一个模板标签 ,它是用大括号和百分号({% %} )表示的。
  • 模板标 签是一小段代码,生成要在网页中显示的信息。
  • 在这个实例中,模板标签{% url 'learning_logs:index' %} 生成一个URL,该URL与learning_logs/urls.py中定义的名为index 的URL模式匹配。
  • 在这个示例中,learning_logs 是一个命名空间 ,而index 是该命名空间中一个名称独特的URL模式。
  • 我们插入了一对块标签。这个块名为content ,是一个占位符,其中包含的信息将由子模板指定。
  • 子模板并非必须定义父模板中的每个块,因此在父模板中,可使用任意多个块来预留空间,而子模板可根据需要定义相应数量的块。
  • 注意
    在Python代码中,我们几乎总是缩进四个空格。相比于Python文件,模板文件的缩进层级更多,因此每个层级通常只缩进两个空格。
在简单的HTML页面中,链接是使用锚标签定义的:
<a href="link_url">link text</a>

让模板标签来生成URL,可让链接保持最新容易得多。要修改项目中的URL,只需修改urls.py中的URL模式,这样网页被请求时,Django将自动插入修改后的URL。在我们的项目中,每个网页都将继承base.html,因此从现在开始,每个网页都包含到主页的链接。

2. 子模板

现在需要重新编写index.html,使其继承base.html,如下所示:
index.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Learning Log helps you keep track of your learning, for any topic you'relearning about.</p>
{% endblock content %}
  • 如果将这些代码与原来的index.html进行比较,可发现我们将标题LearningLog替换成了从父模板那里继承的代码
  • 子模板的第一行必须包含标签{% extends %} ,让Django知道它继承了哪个父模板
  • 文件base.html位于文件夹learning_logs中,因此父模板路径中包含learning_logs。这行代码导入模板base.html的所有内容,让index.html能够指定要在content 块预留的空间中添加的内容。
  • 我们插入了一个名为content 的{% block %} 标签,以定义content 块。不是从父模板继承的内容都包含在content 块中,在这里是一个描述项目“学习笔记”的段落。
  • 我们使用标签{% endblock content %} 指出了内容定义的结束位置。
模板继承的优点开始显现出来了:在子模板中,只需包含当前网页特有的内容。这不仅简化了每个模板,还使得网站修改起来容易得多。要修改很多网页都包含的元素,只需在父模板中修改该元素,你所做的修改将传导到继承该父模板的每个页面。在包含数十乃至数百个网页的项目中,这种结构使得网站改进起来容易而且快捷得多。
在大型项目中,通常有一个用于整个网站的父模板——base.html,且网站的每个主要部分都有一个父模板。每个部分的父模板都继承base.html,而网站的每个网页都继承相应部分的父模板。这让你能够轻松地修改整个网站的外观、网站任何一部分的外观以及任何一个网页的外观。这种配置提供了一种效率极高的工作方式, 让你乐意不断地去改进网站。

        18.4.2 显示所有主题的页面

有了高效的网页创建方法,就能专注于另外两个网页了:显示全部主题的网页以及显示特定主题中条目的网页。所有主题页面显示用户创建的所有主题,它是第一个需要使用数据的网页。

1. URL模式

首先,我们来定义显示所有主题的页面的URL。通常,使用一个简单的URL片段来指出网页显示的信息;我们将使用单词topics,因此URL http://localhost:8000/topics/将返回显示所有主题的页面。下面演示了该如何修改learning_logs/urls.py:
urls.py
"""定义learning_logs的URL模式"""
from django.urls import path# 从当前的urls.py所在文件夹导入views
from . import views
app_name = 'learning_logs'# 包含可在应用程序learning_ logs中请求的网页
urlpatterns = [# 主页path('', views.index, name='index'),# 显示所有主题path('topics/', views.topics, name='topics')
]
我们只是在用于主页URL的正则表达式中添加了topics/ 。Django检查请求的URL时,这个模式与这样的URL匹配:基础URL后面跟着topics 。可以在末尾包含斜杠,也可以省略它,但单词topics 后面不能有任何东西,否则就与该模式不匹配。其URL与该模式匹配的请求都将交给views.py中的函数topics() 进行处理。

2. 视图

函数topics() 需要从数据库中获取一些数据,并将其发送给模板。我们需要在views.py中添加的代码如下:
views.py
from django.shortcuts import render
from .models import Topic# Create your views here.
def index(request):--snip--def topics(request):#显示所有主题topics = Topic.objects.order_by('date_added')context = {'topics':topics}return render(request,'learning_logs/topics.html',context)
  • 我们首先导入了与所需数据相关联的模型。
  • 函数topics() 包含一个形参:Django从服务器那里收到的request 对象。
  • 我们查询数据库——请求提供Topic 对象,并按属性date_added 对它们进行排序。
  • 我们将返回的查询集存储在topics 中。
  • 我们定义了一个将要发送给模板的上下文。上下文是一个字典,其中的键是我们将在模板中用来访问数据的名称,而值是我们要发送给模板的数据。在这里,只有一个键—值对,它包含我们将在网页中显示的一组主题。
  • 创建使用数据的网页时,除对象request 和模板的路径外,我们还将变量context 传递给render() 。

3. 模板

显示所有主题的页面的模板接受字典context ,以便能够使用topics() 提供的数据。请创建一个文件,将其命名为topics.html,并存储到index.html所在的目录中。下面演示了如何在这个模板中显示主题:
topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>{% for topic in topics %}<li>{{ topic }}</li>{% empty %}<li>No topics have been added yet.</li>{% endfor %}
</ul>
{% endblock content %}
  • 就像模板index.html一样,我们首先使用标签{% extends %} 来继承base.html,再开始定义content 块。这个网页的主体是一个项目列表,其中列出了用户输入的主题。在标准HTML中,项目列表被称为无序列表,用标签<ul></ul> 表示。
  • 我们使用了模板标签{% empty %} ,它告诉Django在列表topics 为空时该怎么办:这里是打印一条消息,告诉用户还没有添加任何主题。最后两行分别结束for 循环和项目列表。
我们使用了一个相当于for 循环的模板标签,它遍历字典context 中的列表topics 。模板中使用的代码与Python代码存在一些重要差别:Python使用缩进来指出哪些代码行是for 循环的组成部分,而在模板中,每个for 循环都必须使用{% endfor %} 标签来显式地指出其结束位置。因此在模板中,循环类似于下面这样:
{% for item in list %}
do something with each item
{% endfor %}

在循环中,我们要将每个主题转换为一个项目列表项。要在模板中打印变量,需要将变量名用双花括号括起来。每次循环时,代码{{ topic }} 都被替换为topic 的当前值。这些花括号不会出现在网页中,它们只是用于告诉Django我们使用了一个模板变量。HTML标签<li></li> 表示一个项目列表项,在标签对<ul></ul> 内部,位于标签<li> 和</li> 之间的内容都是一个项目列表项。
现在需要修改父模板,使其包含到显示所有主题的页面的链接:
base.html
<p><a href="{% url 'learning_logs:index' %}">Learning Log</a> -<a href="{% url 'learning_logs:topics' %}">Topics</a>
</p>
{% block content %}{% endblock content %}
我们在到主页的链接后面添加了一个连字符,然后添加了一个到显示所有主题的页面的链接——使用的也是模板标签url 。这一行让Django生成一个链接,它与learning_logs/ urls.py中名为topics 的URL模式匹配。
现在如果你刷新浏览器中的主页,将看到链接Topics。单击这个链接,将看到类似于图18-4所示的网页。

18-4 显示所有主题的网页

        18.4.3 显示特定主题的页面

接下来,我们需要创建一个专注于特定主题的页面——显示该主题的名称及该主题的所有条目。同样,我们将定义一个新的URL模式,编写一个视图并创建一个模板。我们还将修改显示所有主题的网页,让每个项目列表项都是一个链接,单击它将显示相应主题的所有条目。

1. URL模式

显示特定主题的页面的URL模式与前面的所有URL模式都稍有不同,因为它将使用主题的id 属性来指出请求的是哪个主题。例如,如果用户要查看主题Chess(其id 为1)的详细页面,URL将为http://localhost:8000/topics/1/。下面是与这个URL匹配的模式,它包含在learning_logs/urls.py中:
urls.py

"""定义learning_logs的URL模式"""
from django.urls import path,re_path# 从当前的urls.py所在文件夹导入views
from . import views
app_name = 'learning_logs'# 包含可在应用程序learning_ logs中请求的网页
urlpatterns = [# 主页path('', views.index, name='index'),# 显示所有主题path('topics/', views.topics, name='topics'),# 特定主题的详细页面re_path(r'^topics/(?P<topic_id>\d+)/', views.topic, name='topic'),
]
  • 我们来详细研究这个URL模式中的正则表达式——r'^topics/(?P<topic_id>\d+)/' 。r 让Django将这个字符串视为原始字符串,并指出正则表达式包含在引号内。
  • 这个表达式的第二部分(/(?P<topic_id>\d+)/ )与包含在两个斜杠内的整数匹配,并将这个整数存储在一个名为topic_id 的实参中。这部分表达式两边的括号捕获URL中的值;
  • ?P<topic_id> 将匹配的值存储到topic_id 中;
  • 而表达式\d+ 与包含在两个斜杆内的任何数字都匹配,不管这个数字为多少位。
  • 发现URL与这个模式匹配时,Django将调用视图函数topic() ,并将存储在topic_id 中的值作为实参传递给它。
  • 在这个函数中,我们将使用topic_id 的值来获取相应的主题。

2. 视图

函数topic() 需要从数据库中获取指定的主题以及与之相关联的所有条目,如下所示:
views.py
--snip--
def topic(request,topic_id):#显示单个主题及其所有条目topic = Topic.objects.get(id=topic_id)entries = topic.entry_set.order_by('-date_added')context = {"topic":topic,'entries':entries}return render(request,'learning_logs/topic.html',context)
  • 这是第一个除request 对象外还包含另一个形参的视图函数。
  • 这个函数接受正则表达式(?P<topic_id>\d+) 捕获的值,并将其存储到topic_id 中。
  • 我们使用get() 来获取指定的主题,就像前面在Django shell中所做的那样。
  • 我们获取与该主题相关联的条目,并将它们按date_added 排序:date_added 前面的减号指定按降序排列,即先显示最近的条目。
  • 我们将主题和条目都存储在字典context 中,再将这个字典发送给模板topic.html。
注意
topic处和entries处的代码被称为查询,因为它们向数据库查询特定的信息。在自己的项目中编写这样的查询时,先在Django shell中进行尝试大有裨益。相比于编写视图和模板,再在浏览器中检查结果,在shell中执行代码可更快地获得反馈。

3. 模板

这个模板需要显示主题的名称和条目的内容;如果当前主题不包含任何条目,我们还需向用户指出这一点:
topic.html
{% extends "learning_logs/base.html" %}{% block content %}
<p>Topic:{{ topic }}</p>
<ul>{% for entry in entries %}<li><p>{{ entry.date_added|date:'M d, Y H:i'}}</p><p>{{ entry.text|linebreaks }}</p></li>{% empty %}<li>There are no entries for this topic yet.</li>{% endfor %}
</ul>
{% endblock content %}
  • 像这个项目的其他页面一样,这里也继承了base.html。
  • 接下来,我们显示当前的主题,它存储在模板变量{{ topic }} 中。为什么可以使用变量topic 呢?因为它包含在字典context 中。
  • 接下来,我们开始定义一个显示每个条目的项目列表,并像前面显示所有主题一样遍历条目。
  • 每个项目列表项都将列出两项信息:条目的时间戳和完整的文本。为列出时间戳,我们显示属性date_added 的值。在Django模板中,竖线(| )表示模板过滤器—— 对模板变量的值进行修改的函数。过滤器date: 'M d, Y H:i' 以这样的格式显示时间戳:January 1, 2015 23:00。
  • 接下来的一行显示text 的完整值,而不仅仅是entry 的前50个字符。
  • 过滤器linebreaks将包含换行符的长条目转换为浏览器能够理解的格式,以免显示为一个不间断的文本块。
  • 我们使用模板标签{% empty %} 打印一条消息,告诉用户当前主题还没有条目。

4. 将显示所有主题的页面中的每个主题都设置为链接

在浏览器中查看显示特定主题的页面前,我们需要修改模板topics.html,让每个主题都链接到相应的网页,如下所示:
topics.html
--snip
{% for topic in topics %}<li><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></li>{% empty %}
--snip
我们使用模板标签url 根据learning_logs中名为topic 的URL模式来生成合适的链接。这个URL模式要求提供实参topic_id ,因此我们在模板标签url 中添加了属性topic.id。现在,主题列表中的每个主题都是一个链接,链接到显示相应主题的页面,如http://localhost:8000/topics/1/。
如果你刷新显示所有主题的页面,再单击其中的一个主题,将看到类似于图18-5所示的页面。

18-5 特定主题的详细页面,其中显示了该主题的所有条目

18.5 小结

  1. 在本章中,我通过它首先学习了如何使用Django框架来创建Web应用程序。
  2. 根据原有教程制定了简要的项目规范,在虚拟环境中安装了Django,创建了一个项目,并核实该项目已正确地创建。
  3. 同时还学习了如何创建应用程序,以及如何定义表示应用程序数据的模型。
  4. 学习了数据库,以及在修改模型后,Django可为我们迁移数据库提供什么样的帮助。
  5. 学习了如何创建可访问管理网站的超级用户,并使用管理网站输入了一些初始数据。
  6. 还探索了Django shell,它让我们能够在终端会话中处理项目的数据。
  7. 学习了如何定义URL、创建视图函数以及编写为网站创建网页的模板。
  8. 最后,我们使用了模板继承,它可简化各个模板的结构,并使得修改网站更容易。

python编程从入门到实践 第18章Django入门 2022年最新相关推荐

  1. python从入门到实践18章django存在问题_第18章 Django入门 P371

    声音简介-感谢粉丝NN娜娜小天使的打赏,此音频即日起以24小时/天,1次/小时的速度更新,直至完结~ 特别说明: 此音频仅作为更好地阅读此书的辅助工具,请大家购买正版书籍. 所有音频全部免费供大家试听 ...

  2. 第 18 章 Django 入门

    当今的网站实际上都是富应用程序(rich application),就像成熟的桌面应用程序一样.Python提供了一组开发Web应用程序的卓越工具.在本章中,我们将学习如何使用Django(http: ...

  3. 深度学习框架PyTorch入门与实践:第二章 快速入门

    本章主要介绍两个内容,2.1节介绍如何安装PyTorch,以及如何配置学习环境:2.2节将带领读者快速浏览PyTorch中主要内容,给读者一个关于PyTorch的大致印象. 2.1 安装与配置 2.1 ...

  4. Python编程从入门到实践第五章部分习题

    Python编程从入门到实践第五章部分习题 5-8 5-9` names = ['admin','zhang','li','zhao','song'] for name in names:if nam ...

  5. Python编程:从入门到实践 第三章--函数

    Python编程:从入门到实践 第三章-函数 语法 就还是需要先记一下函数定义的语法: def Test(num):num = 12 如上,def func_name(factors): # code ...

  6. Python编程:从入门到实践第六章读书笔记6.3遍历字典

    Python编程:从入门到实践第六章读书笔记6.3遍历字典 #coding:gbk#6.3.1遍历所有的键-值对 user_0 = {'username': 'efermi','first': 'en ...

  7. 读书笔记——《Python编程从入门到实践》第二章

    读书笔记--<Python编程从入门到实践>第二章 读书笔记--<Python编程从入门到实践>第二章 变量 如何使用变量 如何规范变量命名 字符串 字符串是什么 如何修改字符 ...

  8. 《Python编程:从入门到实践》第二章练习题

    <Python编程:从入门到实践>第二章练习题 <Python编程:从入门到实践>第二章练习题 1-1 简单消息 2-2 多条简单消息 2-3 个性化消息 2-4 调整名字的大 ...

  9. Python编程:从入门到实践第六章练习6.3

    Python编程:从入门到实践第六章练习6.3 #coding:gbk#6-4词汇表2 #参照6.3练习.py#6-5河流 rivers = {'nile': 'egypt','yellow rive ...

最新文章

  1. AngularJS基于MVC的复杂操作案例
  2. 关于iPhone 中sqlite文件的使用
  3. Nginx教程--配置
  4. 有关python方面的论文_一篇文章可以带你理解python中的类
  5. 深入研究 Java Synchronize 和 Lock 的区别与用法
  6. 论文笔记 | Counterfactual Samples Synthesizing for Robust VQA
  7. 手机站的view.php,织梦网站文章内容页动态地址plus/view.php路径修改
  8. ASN.1编解码与编程
  9. prim算法_数据结构 7.4.1 最小生成树 Prim
  10. LeetCode 590. N叉树的后序遍历(N-ary Tree Postorder Traversal)
  11. 【Android Developers Training】 1. 创建一个Android项目工程
  12. 尚硅谷kylin单机版之安装kylin
  13. MDM9607 SE1801A安全芯片调试记录
  14. 软件工程概论期末复习笔记
  15. 微信昵称乱码 mysql_微信昵称乱码及mysql编码格式设立(utf8mb4)_mysql
  16. 计算机开机硬件检查,开机bios检测硬件信息方法
  17. 对于有关串口通信的clk的解释
  18. python输出古诗词_python爬虫——爬取古诗词
  19. Hive 多维度聚合分析查询
  20. 使用计算机正确坐姿,如何保持正确坐姿?(多图)

热门文章

  1. 【1999年分区联赛提高组之一】【图论】【最小点覆盖】【匈牙利】拦截导弹
  2. 身为在软件测试摸爬滚打多年工程师的感悟,写给正在迷茫的你!
  3. 启信宝受益所有人界面_希望您的项目成功吗? 然后确保其他人也可以从您的想法中受益。...
  4. 谷粒商城--商品发布--笔记九
  5. 切削技术首页 基础知识 钻镗铣加工 铣削问题与对策
  6. 我们是如何改进YOLOv3进行红外小目标检测的?
  7. Linux面试题目(一)
  8. 设置监察哨的顺序查找
  9. 2021-11-26 WPF上位机 96-Modbus通信代码的封装
  10. ANDROID 系统下载