迁移数据库
实际上这些数据库表还没有真正的在数据库中创建,接下来Django将 Python 代码翻译成数据库语言
manage.py 文件所在的目录下,运行python manage.py makemigrations
Django 在 blog应用的migrations\目录下生成了一个0001_initial.py文件
即 Django用来记录我们对模型做了哪些修改的文件
在 models.py文件里创建有 3个模型类,Django把这些变化记录在了 0001_initial.py
接下来执行python manage.pymigrate命令。
Django 通过检测应用中 migrations\目录下的文件,得知对数据库做了哪些操作,然后把这些操作翻译成数据库操作语言,从而把这些操作作用于真正的数据库。
看到命令的输出除了 Applying blog.0001_initial... OK外,Django还对其它文件做了操作。因为除了我们自己建立的 blog应用外,Django自身还内置了很多应用,这些应用本身也是需要存储数据的。可以在 settings.py的 INSTALLED_APP设置里看到这些应用。
运行python manage.pysqlmigrate blog 0001命令:
输出了经 Django翻译后的数据库表创建语句,这有助于你理解 Django ORM的工作机制。
数据库版本
Python内置的 SQLite3数据库,没有安装任何的数据库软件,Django就帮我们迁移了数据库。
SQLite3是一个十分轻巧的数据库,它仅有一个文件。项目根目录下会多出了一个 db.sqlite3的文件,这就是 SQLite3数据库文件,Django博客的数据都会保存在这个数据库文件里。
Django在 settings.py里为我们做了一些默认的数据库配置:看到默认的数据库引擎就是使用的 SQLite3。
Django 也可以配置 MySQL等大型数据库。可以自行使用搜索引擎或者查阅 Django的官方文档。
用 Django的方式操作数据库
存数据
manage.py所在目录下运行python manage.pyshell命令:打开了一个交互式命令行
首先我们来创建一个分类和一个标签:
导入 3个之前写好的模型类,然后实例化了一个 Category类和一个 Tag类,为其属性 name赋了值。为了让 Django把这些数据保存进数据库,调用实例的 save方法即可。
创建一篇文章
创建文章之前,需要先创建一个 User,用于指定文章的作者。
创建 User的命令Django已经写好了,依然是通过 manage.py来运行。
首先按住 Ctrl + z退出命令交互栏
运行python manage.pycreatesuperuser命令并根据提示创建用户:
再次运行python manage.pyshell
进入 Python 命令交互栏,开始创建文章:
重启 shell,此时需要重新导入了 Category、Tag、Post以及 User
并导入了一个 Django提供的辅助模块 timezone,调用其 now()方法为 created_time和 modified_time指定时间,容易理解 now方法返回当前时间
然后根据用户名和分类名,通过 get方法取出了存在数据库中的 User和 Category
接着为文章指定了 title、body、created_time、modified_time值,并把它和前面创建的 Category 以及 User关联了起来
允许为空 excerpt、tags就没有为它们指定值了
注意:我们这里使用get
方法根据Category
的name
属性的值获取分类的一条记录。Category.objects.get(name='categorytest')
的含义是从数据库中取出name
的值为 category test 的分类记录。确保数据库中只有一条值为 category test的记录,否则get
方法将返回一个MultipleObjectsReturned
异常。如果你不小心已经存了多条记录,请删掉多余的记录。如何删除数据请看下文。也可以删除db.sqlite3文件重新开始本部分。
取数据
objects
是我们的模型管理器,提供一系列从数据库中取数据方法
这里使用了all
方法,表示要把对应的数据全部取出来。
看到all
方法都返回了数据,这些数据应该是之前存进去的,但显示的字符串无法确认
为 3个模型分别增加一个__str__
方法,显示出来的数据更加人性化一点:
Blog/models.py文件:
classCategory(models.Model):
...
def __str__(self):
returnself.name
classTag(models.Model):
...
def __str__(self):
returnself.name
classPost(models.Model):
...
def __str__(self):
returnself.title
定义好__str__
方法后,解释器显示的内容将会是__str__
方法返回的内容。Category
返回分类名name
,Tag
返回标签名
而Post
返回它的title
兼容 Python2:使用python_2_unicode_compatible
装饰器(fromdjango.utils.siximport python_2_unicode_compatible)或者则将__str__
方法改为__unicode__
方法即可
Ctrl + z退出 Shell,再重新运行python manage.py shell
进入 Shell,执行之前命令:
创建文章时通过 get方法来获取数据, all方法和 get方法的区别是:
all 方法返回全部数据,是一个类似于列表的数据结构(QuerySet)
get 返回一条记录数据,如有多条记录或者没有记录,get方法均会抛出相应异常
改数据
首先通过get
方法根据分类名name
获取值为 category test 到分类,修改它的name
属性为新的值 category test new,然后调用save
方法把修改保存到数据库,之后可以看到数据库返回的数据已经是修改后的值了。Tag
、Post
的修改也一样。
删数据
fromblog.modelsimport Category, Tag, Post
先根据标题title
的值从数据库中取出Post
,保存在变量p
中,然后调用它的delete
方法,最后看到Post.objects.all()
返回了一个空的 QuerySet(类似于一个列表),表明数据库中已经没有 Post,Post已经被删除了。
Django官方文档
Django blog - 04 - 博客首页