乐趣区

关于后端:Django笔记三之使用model对数据库进行增删改查

本篇笔记目录索引如下:

  1. 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_list = Blog.objects.all()[1:5]

然而和 python 里的切片不一样的时候,Django 的查问不反对 正数查问,比方上面的操作是不被容许的:

Blog.objects.all()[-1]  # error
Blog.objects.all()[-1: 3]  # error

字段条件查找:
在咱们应用 mysql 的时候 where 前面会跟一些查问的限度条件,在 Django 里用 双下划线来实现
比方 id 的值大于 5

Model.objects.filter(id__gt=5)

大于:gt
大于等于:gte
小于:lt
小于等于:lte
蕴含:in
是否为 null:isnull

准确查找:
准确查找应用 exact,个别查问的时候 前面不加上面的字段条件,都属于准确查找,不过默认是将 exact 字段省略。
比方,上面两条代码是统一的:

Blog.objects.get(id__exact=14)
Blog.objects.get(id=14) 

查问外键关联数据
比方 Entry 这个 model 的外键是 Blog,咱们想通过 查找 Blog 的 name 字段为 Hunter 的 Entry 数据:

Entry.objects.filter(blog__name='Hunter')

如果你想反向搜寻也是能够的,将 model 名称小写即可:

Blog.objects.filter(entry__headline='abc')

计算查找
在 Django 中援用字段来进行比拟,比方咱们想实现如下性能:

select * from blog_entry where number_of_comments > number_of_pingbacks;

能够应用 Django 中的 F,它的作用是 取值,取出其中的字段值,那么上述例子能够用 Django 来实现能够是:

from django.db.models import F
Entry.objects.filter(number_of_comments__gt=F(“number_of_pinbbacks"))

还能够在应用中对 F() 进行一系列的操作:

Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks') * 2)
Entry.objects.filter(rating__lt=F('number_of_comments') + F('number_of_pingbacks'))

pk 应用办法
pk 意思是 primary key,主键,能够间接应用 pk 来搜寻,但在我的项目中个别是应用 id 作为主键,所以个别是等价于 id 的用法:

Blog.objects.filter(pk__gt=11)

Q 查问:
咱们晓得能够应用 filter 来进行 链式查问,那个逻辑是一个且的逻辑,那么 或 的逻辑应该如何解决呢
咱们能够应用 Q() 来实现

咱们能够应用 Q() 来将一个个的条件 串起来,比方,咱们想筛选 Blog 中 id= 3 或者 id = 4 的数据能够应用如下:

Blog.objects.filter(Q(id=3) | Q(id=4))

也能够实现 且 的性能 Q() & Q()
取反:~Q()

4、删

如果要删除 objects,有两种办法,一种先获取 object,而后 delete()

blog = Blog.objects.get(id=1)
blog.delete()

或者通过 filter 来 批量删除:

Blog.objects.filter(id__gte=10).delete()

留神:如果有外键关联了 Blog,且 on_delete 关系设置为 models.CASCADE,
那么删除相应的 Blog 的时候,对应的 关联的 Entry 数据也会被删除

5、改

批量更新:

Blog.objects.filter(id__gte=200).update(name='hunter')

单个更新:

blog = Blog.objects.get(id=1)
blog.name =‘hunter’blog.save()

以上就是咱们这一篇笔记的全部内容,下一篇笔记将具体介绍 Django model 里的 各个字段类型以及字段属性值。

本文首发于自己微信公众号:Django 笔记。
原文链接:Django 笔记三之应用 model 对数据库进行增删改查
如果想获取更多相干文章,可扫码关注浏览:

退出移动版