Django学习笔记(三)

三、创建博客的数据库模型

模型

模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。
所以,创建博客的数据库模型就是设计和创建存储数据的表,模型体现出来的就是表

  • 每个模型都是django.db.models.Model 的一个Python 子类。 模型是一个python类,继承django.db.models.Model
  • 模型的每个属性都表示为数据库中的一个字段。
  • Django 提供一套自动生成的用于数据库访问的API

例子

这个例子定义一个Person模型,它有first_name 和last_name 两个属性:


1
2
3
4
5
6
7
from django.db import models

class Person(models.Model):

first_name = models.CharField(max_length=30)

last_name = models.CharField(max_length=30)

first_name和last_name是模型的两个字段。每个字段都被指定成一个类属性,每个属性映射到一个数据库的列。

上面的Person 模型会在数据库中创建这样一张表:


1
2
3
4
5
6
7
8
9
CREATE TABLE myapp_person (

"id" serial NOT NULL PRIMARY KEY,

"first_name" varchar(30) NOT NULL,

"last_name" varchar(30) NOT NULL

);

一些技术上的注意事项:

  • 这个表的名称myapp_person,是根据 模型中的元数据自动生成的,也可以重写为别的名称
  • id 字段是自动添加的,但这个行为可以被重写。详见自增主键字段。
  • 这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据设置文件 中指定的数据库类型来使用相应的SQL 语句。

设计和创建

文章id 标题 正文 发表时间 分类 标签
1 title 1 text 1 2016-12-23 Django Django 学习
2 title 2 text 2 2016-12-24 Django Django 学习
3 title 3 text 3 2016-12-26 Python Python 学习

其中文章 ID 是一个数字,唯一对应着一篇文章。当然还可以有更多的列以存储更多相关数据,这只是一个最基本的示例。
数据库表设计成这样其实已经可以了,但是稍微分析一下我们就会发现一个问题,这 3
篇文章的分类和标签都是相同的,这会产生很多重复数据,当数据量很大时就浪费了存储空间。
不同的文章可能它们对应的分类或者标签是相同的,所以我们把分类和标签提取出来,做成单独的数据库表,再把文章和分类、标签关联起来。下面分别是分类和标签的数据库表:

分类 id 分类名
1 Django
2 Python
标签 id 标签名
1 Django 学习
2 Python 学习

编写的代码

在app目录下的models.py文件进行编写


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 blog/models.py

from django.db import models

from django.contrib.auth.models import User

class Category(models.Model):

"""

Django 要求模型必须继承 models.Model 类。

Category 只需要一个简单的分类名 name 就可以了。

CharField 指定了分类名 name 的数据类型,CharField 是字符型,

CharField 的 max_length 参数指定其最大长度,超过这个长度的分类名就不能被存入数据库。

当然 Django 还为我们提供了多种其它的数据类型,如日期时间类型 DateTimeField、整数类型 IntegerField 等等。

Django 内置的全部类型可查看文档:

https://docs.djangoproject.com/en/1.10/ref/models/fields/#field-types

"""

name = models.CharField(max_length=100)

class Tag(models.Model):

"""

标签 Tag 也比较简单,和 Category 一样。

再次强调一定要继承 models.Model 类!

"""

name = models.CharField(max_length=100)

class Post(models.Model):

"""

文章的数据库表稍微复杂一点,主要是涉及的字段更多。

"""

# 文章标题

title = models.CharField(max_length=70)

# 文章正文,我们使用了 TextField。

# 存储比较短的字符串可以使用 CharField,但对于文章的正文来说可能会是一大段文本,因此使用 TextField 来存储大段文本。

body = models.TextField()

# 这两个列分别表示文章的创建时间和最后一次修改时间,存储时间的字段用 DateTimeField 类型。

created_time = models.DateTimeField()

modified_time = models.DateTimeField()

# 文章摘要,可以没有文章摘要,但默认情况下 CharField 要求我们必须存入数据,否则就会报错。

# 指定 CharField 的 blank=True 参数值后就可以允许空值了。

excerpt = models.CharField(max_length=200, blank=True)

# 这是分类与标签,分类与标签的模型我们已经定义在上面。

# 我们在这里把文章对应的数据库表和分类、标签对应的数据库表关联了起来,但是关联形式稍微有点不同。

# 我们规定一篇文章只能对应一个分类,但是一个分类下可以有多篇文章,所以我们使用的是 ForeignKey,即一对多的关联关系。

# 而对于标签来说,一篇文章可以有多个标签,同一个标签下也可能有多篇文章,所以我们使用 ManyToManyField,表明这是多对多的关联关系。

# 同时我们规定文章可以没有标签,因此为标签 tags 指定了 blank=True。

# 如果你对 ForeignKey、ManyToManyField 不了解,请看教程中的解释,亦可参考官方文档:

# https://docs.djangoproject.com/en/1.10/topics/db/models/#relationships

category = models.ForeignKey(Category)

tags = models.ManyToManyField(Tag, blank=True)

# 文章作者,这里 User 是从 django.contrib.auth.models 导入的。

# django.contrib.auth 是 Django 内置的应用,专门用于处理网站用户的注册、登录等流程,User 是 Django 为我们已经写好的用户模型。

# 这里我们通过 ForeignKey 把文章和 User 关联了起来。

# 因为我们规定一篇文章只能有一个作者,而一个作者可能会写多篇文章,因此这是一对多的关联关系,和 Category 类似。

author = models.ForeignKey(User)

代码详解

首先是 Category 和 Tag 类,它们均继承自 model.Model 类,这是 Django 规定的。Category 和 Tag
类均有一个name 属性,用来存储它们的名称。由于分类名和标签名一般都是用字符串表示,因此我们使用了 CharField 来指定 name 的数据类型,同时
max_length 参数则指定 name 允许的最大长度,超过该长度的字符串将不允许存入数据库。除了 CharField ,Django
还为我们提供了更多内置的数据类型,比如时间类型 DateTimeField、整数类型 IntegerField 等等。

Post 类也一样,必须继承自 model.Model 类。文章的数据库表稍微复杂一点,主要是列更多,我们指定了这些列:

  • title。这是文章的标题,数据类型是 CharField,允许的最大长度 max_length = 70。
  • body。文章正文,我们使用了 TextField。比较短的字符串存储可以使用 CharField,但对于文章的正文来说可能会是一大段文本,因此使用 TextField 来存储大段文本。
  • created_time、modified_time。这两个列分别表示文章的创建时间和最后一次修改时间,存储时间的列用 DateTimeField 数据类型。
  • excerpt。文章摘要,可以没有文章摘要,但默认情况下 CharField 要求我们必须存入数据,否则就会报错。指定 CharField 的 blank=True 参数值后就可以允许空值了。
  • category 和 tags。这是分类与标签,分类与标签的模型我们已经定义在上面。我们把文章对应的数据库表和分类、标签对应的数据库表关联了起来,但是关联形式稍微有点不同。我们规定一篇文章只能对应一个分类,但是一个分类下可以有多篇文章,所以我们使用的是 ForeignKey,即一对多的关联关系。而对于标签来说,一篇文章可以有多个标签,同一个标签下也可能有多篇文章,所以我们使用 ManyToManyField,表明这是多对多的关联关系。同时我们规定文章可以没有标签,因此为标签 tags 指定了 blank=True。
  • author。文章作者,这里 User 是从 django.contrib.auth.models 导入的。django.contrib.auth 是 Django 内置的应用,专门用于处理网站用户的注册、登录等流程。其中 User 是 Django 为我们已经写好的用户模型,和我们自己编写的 Category 等类是一样的。这里我们通过 ForeignKey 把文章和 User关联了起来,因为我们规定一篇文章只能有一个作者,而一个作者可能会写多篇文章,因此这是一对多的关联关系,和 Category 类似。

要点总结

1、 模型的概念的理解

创建博客的数据库模型就是设计和创建存储数据的表,模型体现出来的就是表

2、模型实际是在代码中实际就是一个python类,继承model类

-------------本文结束感谢您的阅读-------------