你好,我是goldsunC
让我们一起进步吧!
从0到1搭建个人博客-Django(四)
在以下链接快速回顾系列文章内容
环境准备
这一篇文章我们开始编写APP模型Model
。上一篇文章已经介绍过ORM(对象关系映射)
,也就是说在Django中,每一个模型类就相当于数据库中的一张表,那我们创建好模型类进行使用如实例化的时候,就相当于在数据库中产生了数据,既然数据库产生了数据就避免不了查看其中的数据,因此我们需要安装一个可以查看数据库中数据的软件,这里使用SQLiteStudio
软件,可以去网站下载:
https://github.com/pawelsalawa/sqlitestudio/releases
,也可以在公众号回复SQLite
获取安装包。
第一个Model
上一篇我们已经讲过,Django中通过模型(Model)
映射到数据库,处理与数据相关的事务,我们的一个Model类就相当于数据库中的一个表,那我们就首先来建立一个存放文章的数据模型。
打开article
下的models.py
文件,可以看到里面还是空空如也,只有两行代码:
from django.db import models
# Create your models here.
第一行也就是导入models
模块,还记得上一篇内容吗,所有数据模型应该为django.db.models.Model
的子类。第二行就提示你在这个文件中建立数据模型了。
OK,我们可以打开自己的编辑器了,在其中加上一些代码,更改完后的models.py
如下:
from django.db import models
# 导入内建的User模型。
from django.contrib.auth.models import User
# timezone 用于处理时间相关事务。
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)
# 内部类 class Meta 用于给 model 定义元数据
class Meta:
# ordering 指定模型返回的数据的排列顺序
# '-created' 表明数据应该以倒序排列
ordering = ('-created',)
# 函数 __str__ 定义当调用对象的 str() 方法时的返回值内容
def __str__(self):
# return self.title 将文章标题返回
return self.title
ArticlePost
类就是我们建立的第一个数据模型类,它就继承自django.db.models.Model
,也就是说它继承了操作数据库能够使用的方法。
代码中有几个字段CharField
、TextField
、DateTimeField
,它们代表相应的数据类型,其中:
-
CharField
代表title
是一个字符串,它有一个参数max_length
,限定了字符串的长度。 -
TextField
也说明body
是一个字符串,不过它没有参数,也就是说它代表一个不限长度的文本字符串。 -
DateTimeField
代表created和updated
是时间日期字段。 -
第一行的
ForeignKey
方法将每一个Article
对象都关联到一个User
对象。 -
其中的内部类
Meta
中的ordering
定义了数据的排列方式,-created
表示将文章以创建时间的倒序排列,保证新建的文章总是在网页上面,注意ordering
是一个元组,不要忘了最后的逗号。 -
__str__
方法定义了需要表示数据时应该显示的名称,它就是Django管理后台中对象的显示值。
上面的内容一点都不理解的话建议再读几遍文章(二),觉得稍微能理解了之后可以先看后面内容,之后再回过头来对比它们的作用。
外键(ForeignKey)
上面模型类中几个字段比较好理解,主要是那一个特殊的方法ForeignKey
。
首先我们知道数据库中由存放各种数据的表组成,有时候几张表是相互关联的,例如a表中的某一列记录的是b表的主键
,那b表的主键也就叫做a表的外键。那这样做的好处是什么呢?举个例子:
如果b表的主键记录的是一个公司的所有供应商信息,显然每一个供应商都是唯一的,那如果用供应商名字作为主键没问题,然后a表记录的是各个供应商的商品信息,b表中的供应商名字作为a表的外键,每一家供应商肯定不止一种商品,但是每一种商品的供应商是唯一的,这样我们就可以通过供应商的名字在a表中找到所有它的产品了。
在我们的ArticlePost
模型中,一篇文章只能有一个作者,而一个作者可以有很多篇文章,这就是典型的"一对多"关系。通过ForignKey
,将User
和ArticlePost
关联到一起,也就是将博客文章的作者和网站的用户联系在一起了。
内部类
模型中定义了一个内部类Meta
,它用来提供模型的元数据。元数据是任何不是字段的东西,例如排序选项ordering
、db_table
等这些信息不是某篇文章的私有数据,而是整张表的共同行为。写不写内部类都行,只不过有了它使得类更加规范。
数据迁移(Migrations)
编写好了Model后,接下来需要进行数据迁移,迁移时是Django对模型所做的更改传递到数据库中的方式。
为什么要迁移呢?什么时候迁移呢?
我们说模型类就是一张表,那我们修改了模型类,按道理来说表中的字段等也就相应被修改了。它们是映射的关系,但并没有完全捆绑在一起,也就是说,你修改了模型类之后,得手动更新
一下数据库表,简单来讲迁移就是更新的过程。
如何迁移?
首先在虚拟环境进入my_blog
项目文件夹中,输入如下代码:
python manage.py makemigrations
命令行会输出:
Migrations for 'article':
article\migrations\0001_initial.py
- Create model ArticlePost
注意提示:Create moedel ArticlePost
,也就是创建好了ArticlePost
类,同时在article\migrations\0001_initial.py
文件,大家可以去文件夹下看看,这个脚本文件就是相应要进行的数据库操作代码,然后再输入:
python manage.py migrate
命令行输出:
Operations to perform:
Apply all migrations: admin, article, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying article.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK
这样就把模型迁移到数据库中了。就实现了更新。
刚才上面的两部操作可以简单理解为首先第一步告诉Django我们改了模型文件,然后Django就回去检测你对模型的修改,然后做好迁移准备,第二步就是确认的过程,Django就执行命令了,实现迁移。
简单理解迁移就是模型类的更新,那什么时候需要迁移?先然只要你修改了模型类就需要迁移呀。依次执行两条命令就实现了迁移。
因此!每当你修改了模型类,就需要执行上面的两条指令!
查看数据库
这个时候可以打开我们安装好的SQLiteStudio
软件,在Database
菜单栏选择Add a Database
,打开my_blog
下的db.sqlite3
文件,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l1mBaiLD-1602667657441)(https://i.loli.net/2020/10/13/ynz9o8d2v6j5LIC.png)]
可以看到已经有了article_articlepost
表,他就是我们创建的那个模型类,里面有我们定义好的字段,不过Data
栏还是空的,因为我们并没有创建文章。
管理员后台
在Django中,内置了一个很好的后台管理工具,可以很方便的增删查改我们定义好的模型数据。不过首先需要创建一个超级管理员
账号,用来管理后台。
在虚拟环境的项目文件夹my_blog
下,输入:
python manage.py createsuperuser
然后根据指令提示输入用户名、邮箱和密码。如下:
Username (leave blank to use '24280'): goldsunC
Email address: goldsunCkn@163.com
Password:
Password (again):
Superuser created successfully.
需要注意的是,输入密码的时候并没有字符提示,不要怀疑你的密码没有输入进去,这和Linux是一样的,不过还是要确认一下你的NUmLock
。
注册ArticlePost
我们之前建立了ArticlePost模型类,也进行了数据迁移,不过虽然有了这个模型类,我们在后台里面还没法管理它,需要把它注册到管理员后台。
打开article/admin.py
,写入以下代码:
from django.contrib import admin
from .models import ArticlePost
# 注册ArticlePost
admin.site.register(ArticlePost)
这样我们就可以在管理员后台管理这个文章的模型类了。
进入管理员后台
启动runserver
,打开浏览器,输入http://127.0.0.1:8000/admin/
,看看发生了什么?不过这里可以稍等一下,为什么这里我们不用配置后台的url路由
了呢?如果你完全理解了前面文章中关于路由的配置,那你应该就发现了,在my_blog\urls.py
中,Django已经帮我们配置好了后台的路由,对,也就是admin
,不信你可以去看一下。
好的,我们启动服务器,输入http://127.0.0.1:8000/admin/
,不出意外的话是如下界面:
输入刚才你创建的管理员账号,登录进去:
可以清楚的看到,里面有了我们创建的ArticlePosts
,点击Add
:
看到里面的Author
、Title
、Body
、Created
字段了吗,跟我们创建的字段完全符合,它们的格式也就是我们之前简单说过的Field的类型,不过为什么没有updated
?这是因为我们创建的时候auto_now=True
参数让它自动填写隐藏了,如果为False它也会出现的。
这个时候我们在打开的ArticlePosts
里面写一些东西,然后点击右下角的SAVE
保存。保存之后如下所示:
保存了之后会发生什么?当然是我们的数据库里面会有数据了!
再用SQLiteStudio
打开我们的db.sqlite3
文件:
如图,我们的ArticlePost
表中已经有了我们刚才写入的数据!
还记得上一篇文章中的MTV流程图吗?本篇文章我们已经实现了Model与数据库的交流功能。
参考文献:
- https://www.dusaiphoto.com/article/2/
- https://docs.djangoproject.com/en/3.1/intro/
- http://c.biancheng.net/view/7288.html
- http://www.python3.vip/tut/webdev/django/