Django学习笔记(三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mango_haoming/article/details/76997505

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

模型

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

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

例子

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

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 模型会在数据库中创建这样一张表:

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文件进行编写

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类

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页