美文网首页Django笔记
Django笔记三之使用model对数据库进行增删改查

Django笔记三之使用model对数据库进行增删改查

作者: vv安的浅唱 | 来源:发表于2023-02-21 21:39 被阅读0次

    本篇笔记目录索引如下:

    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里的 各个字段类型以及字段属性值。

    原文链接:https://mp.weixin.qq.com/s/Hydi5ERZl3_c0bxrU9Q74A

    相关文章

      网友评论

        本文标题:Django笔记三之使用model对数据库进行增删改查

        本文链接:https://www.haomeiwen.com/subject/ucyokdtx.html