Django 框架主要关注的是模型(Model)、模板(Template)和视图(Views),称为MTV模式。
它们各自的职责如下:
层次 | 职责 |
---|---|
模型(Model),即数据存取层 | 处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。 |
模板(Template),即业务逻辑层 | 处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。 |
视图(View),即表现层 | 存取模型及调取恰当模板的相关逻辑。模型与模板的桥梁。 |
简单来说就是Model存取数据,View决定需要调取哪些数据,而Template则负责将调取出的数据以合理的方式展现出来。
数据库与模型
数据库是存储电子文件的场所,储存独立的数据集合。一个数据库由多个数据表构成。
啥意思?举个栗子,三年级二班中同学们的花名册就是数据表。有的花名册记录每位同学的考试成绩、有的记录身高体重、还有的记录兴趣爱好...所有的这些花名册都放在老师的柜子里,这个柜子就是“数据库”了。
默认情况下,数据库就是db.sqlite3这个文件了。在网站上线后你可能想换别的数据库,不过目前我们还不需要讨论这个内容。
操作数据库使用的是复杂的SQL语句,它是完全不同于Python的另一种语言,这对新手来说无疑是困难的。
幸运的是,在 Django 里写Web应用并不需要你直接去操作数据库,而是定义好模型(用Python语法就可以了!),模型中包含了操作数据库所必要的命令。也就是说你只需要定义数据模型,其它的底层代码都不用关心,它们会自动从模型生成。
其实它有专门的术语,叫对象关系映射(Object Relational Mapping,简称ORM),用于实现面向对象编程语言里不同类型系统的数据之间的转换。
编写Model.py
如前面所讲,Django中通过模型(Model)映射到数据库,处理与数据相关的事务。
对博客网站来说,最重要的数据就是文章。所以首先来建立一个存放文章的数据模型。
打开article/models.py
文件,输入如下代码:
from django.db import models
# Create your models here.
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
#博客文章数据模型
class ArticlePost(models.Model):
# 文章作者,参数 on_delete 用于指定数据删除的方式
author = models.ForeignKey(User,on_delete=models.CASCADE)
# 文章标题。models.CharField 为字符串字段,用于保存较短的字符串,比如标题
title = models.CharField(max_length=100)
# 文章正文。保存大量文本使用 TextField
body = models.TextField()
# 文章创建时间。参数 default=timezone.now 指定其在创建数据时将默认写入当前的时间
created = models.DateTimeField(default=timezone.now)
# 文章更新时间。参数 auto_now=True 指定每次数据更新时自动写入当前时间
updated = models.DateTimeField(auto_now=True)
代码非常直白。
-
每个模型都被表示为
django.db.models.Model
类的子类,从它继承了操作数据库需要的所有方法。 -
每个字段都是
Field
类的实例 。比如字符字段被表示为CharField
,日期时间字段被表示为DateTimeField
。这将告诉Django要处理的数据类型。 -
定义某些
Field
类实例需要参数。例如CharField
需要一个max_length
参数。这个参数的用处不止于用来定义数据库结构,也用于验证数据。 -
使用
ForeignKey
定义一个关系。这将告诉 Django,每个(或多个)ArticlePost
对象都关联到一个User
对象。
Django具有一个简单的账号系统(User),满足一般网站的用户相关的基本功能。
ArticlePost
类定义了一篇文章所必须具备的要素:作者、标题、正文、创建时间以及更新时间。
我们还可以额外再定义一些内容,规范ArticlePost
中数据的行为:
article/model.py
class ArticlePost(models.Model):
...
# 内部类 class Meta 用于给 model 定义元数据
class Meta:
# ordering 指定模型返回的数据的排列顺序
# '-created' 表明数据应该以倒序排列
ordering = ('-created',)
# 函数 __str__ 定义当调用对象的 str() 方法时的返回值内容
def __str__(self):
# return self.title 将文章标题返回
return self.title
整理并去掉注释,全部代码放在一起是这样:
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
class ArticlePost(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
body = models.TextField()
created = models.DateTimeField(default=timezone.now)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-created',)
def __str__(self):
return self.title
数据迁移(Migrations)
编写好了Model后,接下来就需要进行数据迁移。迁移是Django对模型所做的更改传递到数据库中的方式。
注意,每当对数据库进行了更改(添加、修改、删除等)操作,都需要进行数据迁移。
Django的迁移代码是由模型文件自动生成的,它本质上只是个历史记录,Django可以用它来进行数据库的滚动更新,通过这种方式使其能够和当前的模型匹配。
在虚拟环境中进入my_blog
文件夹(还没熟悉venv的再温习: 在Windows中搭建Django的开发环境),输入python manage.py makemigrations
,对模型的更改创建新的迁移文件:
(env) D:\django_project\my_blog>python manage.py makemigrations
Migrations for 'article':
article\migrations\0001_initial.py
- Create model ArticlePost
(env) D:\django_project\my_blog>
上面只是创建了一个迁移文件.
通过运行 makemigrations
命令,Django 会检测你对模型文件的修改,并且把修改的部分储存为一次迁移。
然后输入python manage.py migrate
,应用迁移到数据库中:
(env) D:\django_project\my_blog>python manage.py migrate
Operations to perform:
Apply all migrations: admin, article, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
...
Applying sessions.0001_initial... OK
(env) D:\django_project\my_blog>
migrate
命令选中所有还没有执行过的迁移并应用在数据库上,也就是将模型的更改同步到数据库结构上。迁移是非常强大的功能,它能让你在开发过程中持续的改变数据库结构而不需要重新删除和创建表。它专注于使数据库平滑升级而不会丢失数据。
再重复一次:每当你修改了models.py
文件,都需要用makemigrations
和migrate
这两条指令迁移数据。
在迁移之后,Model的编写就算完成了.