本文首发于微信公众号:Hunter后端
原文链接:Django笔记三之使用model对数据库进行增删改查
本篇笔记目录索引如下:
- model 准备
- 增
- 查
- 删
- 改
1、model 准备
在上一篇笔记中,我们新建了一个 application,增加了几个model 同步到了数据库,这次我们新建一个名为 blog 的application,同步数据结构。
大概分为以下几步:
- python3 manage.py startapp blog
- 将 'blog.apps.BlogConfig’, 写入 settings.py INSTALLED_APPS
- 更新 blog/models.py
- python3 manage.py makemigrations blog
- python3 manage.py migrate blog
具体执行 migrate 的操作步骤,可以参见上一篇笔记。
blog/models.py 的具体内容如下:
# blog/models.py
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
number_of_comments = models.IntegerField()
number_of_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.headline
2、增
有以下几种方法(以下操作皆在 python3 manage.py shell 环境中进行):
实例化,然后save() 保存
from blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()
当执行 save() 操作之后,数据就会创建到数据库,因为主键 id 为自动增长的,所以id会自动赋值。
当然也可以先实例化一个空的 Blog,然后再赋值:
from blog.models import Blog
b = Blog()
b.name = 'hunter'
b.tagline = 'tag lines'
b.save()
save 之后,如果需要修改 name 的值,可以直接进行修改:
b.name = ‘python’
b.save()
使用 create() 方法创建
from blog.models import Blog
b = Blog.objects.create(name='hunter', tagline='tagline')
调用 create() 方法,会返回这条数据保存后的对象。
批量创建
如果要批量创建数据,用上面的方法大概的就是在一个循环里,挨个去实例化一个 Blog,然后执行 save() 操作。
但Django 提供了一个 bulk_create() 的方法,可以提高这个效率,使用示例如下:
from blog.models import Blog
blog_1 = Blog(name='hunter1', tagline='tagline1')
blog_2 = Blog(name='hunter2', tagline='tagline2')
blog_obj_list = [blog_1, blog_2]
Blog.objects.bulk(blog_obj_list)
3、查
查询的语法有查询之后返回 QuerySet 的查询,比如 filter(),exclude()
也有 返回单个 object 的查询,比如 get()
对于 QuerySet,这个我们可以简单理解为是多个 object 实例形成的列表,但是这个列表是Django的一种特有的形式,具有能进行其他条件筛选的功能。
接下来简单介绍一下查询的功能:
filter(),过滤筛选,返回的是符合条件的数据
比如我们要搜索 Entry 表里,name 的值为 hunter 的数据,使用如下:
Entry.objects.filter(name='hunter')
exclude(),排除筛选,返回的是不符合条件的数据
比如我们要搜索 Entry 表里,name 的值不为 hunter 的数据:
Entry.objects.exclude(name='hunter')
链式查询:
Django 支持 链式查询,可以多个 filter 或者 exclude 条件累加,取的是 AND 的逻辑:
Entry.objects.filter(name='hunter').exclude(name='paul').filter(id=1)
懒加载:
Django 的查询有一个机制叫做懒加载,意思是只有当你真正需要去取数据的时候
系统才会去数据库获取数据,官方例子如下:
>>> q = Entry.objects.filter(headline__startswith="What")
>>> q = q.filter(pub_date__lte=datetime.date.today())
>>> q = q.exclude(body_text__icontains="food")
>>> print(q)
上述语句虽然看起来查询了三次数据库,但实际上只有最后 print(q) 的时候才去访问了数据库。
get()
前面讲的 filter 和 exclude 返回的都是 QuerySet,简单来说就是多个 object 形成的列表,而 get() 操作返回的直接是一条符合条件的 object。
比如:
blog = Blog.objects.get(id=1)
注意: get() 方法需要慎用,因为查询的条件在数据库里,有多条或者一条都没有的时候系统会报错。
get() 的查询一般仅用在我们能够确定 在数据库里有且仅有一条数据情况下。
对QuerySe进行切片
用 filter 对数据进行操作的时候,如果需要对数据的返回数量进行限制,需要用到 python 里的切片。
PS:数量的返回限制对应于 mysql 里的 limit 用法。
比如:
blog