• django的数据库操作-16


    Django的manage工具提供了shell命令,已经帮助我们配置好当前工程的运行环境(如连接好数据库等),我们会在自带终端中执行测试python语句。

    manage.py 所在目录执行命令

    python manage.py shell
    

    这打开了一个交互式命令行。

    导入模型类

    from book.models import Book
    from book.models import Role
    

    导入date包处理时间

    from datetime import date
    

    增加数据有两种方式

    1.save

    创建模型类对象,再使用 save 保存到数据库中

    新增书籍 “西游记”

    book = Book(
        b_title="西游记", 
        b_pub_date=date(1988,1,1), 
        b_read=20, 
        b_comment=10, 
        is_delete=False)
        
    >>> book.save()
    

    2.create

    直接保存到数据库中

    “西游记”书籍新增角色 “孙悟空”

    Role.objects.create(
    r_name="孙悟空", 
    r_gender="1", 
    r_describe="猴哥", 
    r_book_id=book.id)
    
    
    

    1.基本查询

    get 查询单一结果,如果不存在会抛出模型类.DoesNotExist异常,返回一个模型类对象。

    all 查询多个结果,返回一个查询集。

    count 查询结果数量。

    get

    get 查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。

    查询编号为5的书籍

    >>> Book.objects.get(pk=5)
    <Book: Book object>
    

    objects 是模型管理器,会在后边有具体的讲解。

    pk代表primary key的缩写,也就是任何model中都有的主键,当id也是主键的时候,我们可以认为pk和id是完全一样的。但是当model的主键不是id的时候,两者就有了区别。

    输出出来的 <Book: Book object> 无法看出是不是我们写进去的数据,为了让显示更人性化,我们给数据库模型添加一个 _str__ 方法。

    class Book(models.Model):
        ...
        def __str__(self):
            return self.b_title
    
    class Role(models.Model):
        ...
        def __str__(self):
            return self.r_name
    

    重启shell,重新导入模型类

    >>> Book.objects.get(id=5)
    <Book: 西游记>
    

    all

    all 查询多个结果。

    查询所有书

    >>> Book.objects.all()
    <QuerySet [<Book: 射雕英雄传>, <Book: 天龙八部>, <Book: 笑傲江湖>, <Book: 雪山飞狐>, <Book: 西游记>]>
    

    count

    count 查询结果数量。

    获得书籍数量

    >>> Book.objects.count()
    5
    

    2.过滤查询

    过滤查询实现sql语句中的 where 功能,包括:

    filter 过滤出多个结果,返回一个查询集

    exclude 排除掉符合条件剩下的结果,返回一个查询集

    get 过滤单一结果

    过滤查询语法:

    模型类名.objects.查询方式(过滤条件)
    

    过滤条件语法:

    字段名称__条件运算符=值
    

    条件运算符:

    exact:相等。
    
    contains:包含。
    
    startswith:指定值开头
    
    endswith:指定值结尾
    
    isnull:是否为null。
    
    in:是否包含在范围内。
    
    gt: 大于 (greater then)
    
    gte: 大于等于 (greater then equal)
    
    lt: 小于 (less then)
    
    lte: 小于等于 (less then equal)
    
    year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。
    

    相等

    exact:表示相等

    查询书名等于“西游记”的书

    >>> Book.objects.filter(b_title__exact="西游记")
    <QuerySet [<Book: 西游记>]>
    

    包含(模糊查询)

    contains:包含

    书名包含“八”字的书

    >>> Book.objects.filter(b_title__contains="八")
    <QuerySet [<Book: 天龙八部>]>
    
    

    开头

    书名“笑”开头的数

    >>> Book.objects.filter(b_title__startswith="笑")
    <QuerySet [<Book: 笑傲江湖>]>
    

    结尾

    >>> Book.objects.filter(b_title__endswith="狐")
    <QuerySet [<Book: 雪山飞狐>]>
    

    isnull:是否为null

    书名不为空

    >>> Book.objects.filter(b_title__isnull=False)
    <QuerySet [<Book: 射雕英雄传>, <Book: 天龙八部>, <Book: 笑傲江湖>, <Book: 雪山飞狐>, <Book: 西游记>]>
    

    包含(范围)

    in:是否包含在范围内

    编号 1,2,3的书

    >>> Book.objects.filter(pk__in=[1, 2, 3])
    <QuerySet [<Book: 射雕英雄传>, <Book: 天龙八部>, <Book: 笑傲江湖>]>
    

    大于小于

    gt: 大于 (greater then)
    gte: 大于等于 (greater then equal)
    lt: 小于 (less then)
    lte: 小于等于 (less then equal)
    

    编号大于3的书

    >>> Book.objects.filter(pk__gt=3)
    <QuerySet [<Book: 雪山飞狐>, <Book: 西游记>]>
    

    时间

    year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。

    1995年的书

    >>> Book.objects.filter(b_pub_date__year="1995")
    <QuerySet [<Book: 笑傲江湖>]>
    

    3. F对象

    F()是代表模型字段的值,可以用来修改字段或者比较字段。

    导入F对象

    from django.db.models import F
    

    F对象使用

    F(字段名)
    

    阅读量大于评论量

    >>> Book.objects.filter(b_read__gt=F('b_comment'))
    <QuerySet [<Book: 雪山飞狐>, <Book: 西游记>]>
    

    阅读量大于评论量两倍

    >>> Book.objects.filter(b_read__gt=F('b_comment')*2)
    <QuerySet [<Book: 雪山飞狐>]>
    

    4. Q对象

    随着程序的复杂,查询条件也会越来越复杂,类似前边的查询语句也会变得越来越长。

    例如查询阅读量大于20且评论数大于30的书,需要这样

    >>> book = Book.objects.filter(b_read__gt=20)
    >>> book.filter(b_comment__gt=30)
    <QuerySet [<Book: 天龙八部>]>
    

    或者这样

    >>> Book.objects.filter(b_read__gt=20).filter(b_comment__gt=30)
    <QuerySet [<Book: 天龙八部>]>
    

    但是这样的语句是相当繁杂且不利于阅读的。

    Q()对象就是为了将这些条件组合起来。

    Q对象可以使用 & | ~ 连接,& 表示逻辑与, | 表示逻辑或,~ 表示非。
    类似sql语句中where部分的 and or not 关键字。

    导入Q对象

    from django.db.models import Q
    

    使用Q对象实现查询阅读量大于20且评论数大于30的书

    >>> Book.objects.filter(Q(b_read__gt=20)&Q(b_comment__gt=30))
    <QuerySet [<Book: 天龙八部>]>
    

    5. 聚合函数

    使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和。

    需要从 django.db.models 中导入,例如

    from django.db.models import Sum
    

    查询最多阅读数

    >>> Book.objects.aggregate(Max('b_read'))
    {'b_read__max': 58}
    

    聚合函数查询结果是一个字典类型

    {'字段名__聚合类小写': 查询结果}
    

    6. 排序

    使用 order_by 对查询结果排序,返回一个查询集。

    按阅读量排序

    >>> Book.objects.all().order_by('b_read')  # 升序排序
    <QuerySet [<Book: 射雕英雄传>, <Book: 笑傲江湖>, <Book: 西游记>, <Book: 天龙八部>, <Book: 雪山飞狐>]>
    >>> Book.objects.all().order_by('-b_read')  # 降序排序
    <QuerySet [<Book: 雪山飞狐>, <Book: 天龙八部>, <Book: 笑傲江湖>, <Book: 西游记>, <Book: 射雕英雄传>]>
    

    7. 关联查询

    一查多

    语法

    一方查询对象.多方模型类名小写__set
    

    查询“天龙八部”所有的角色

    >>> book = Book.objects.get(b_title__exact="天龙八部")
    >>> book.role_set.all()
    <QuerySet [<Role: 乔峰>, <Role: 段誉>, <Role: 虚竹>, <Role: 王语嫣>]>
    

    多查一

    语法

    多方查询对象.多方有对应关系的字段名
    

    查询“段誉”所在书名

    >>> role = Role.objects.get(r_name__exact="段誉")
    >>> role.r_book
    <Book: 天龙八部>
    

    8. 关联+过滤查询

    根据多方条件查一方

    语法格式

    多方模型类名小写__多方字段名__条件运算符=值
    

    查询编号为1角色所在书籍

    >>> Book.objects.filter(role__id__exact=1)
    <QuerySet [<Book: 射雕英雄传>]>
    

    查询角色名字带“黄”字的书籍

    >>> Book.objects.filter(role__r_name__contains="黄")
    <QuerySet [<Book: 射雕英雄传>, <Book: 射雕英雄传>]>
    

    当查询条件为等于的时候可以省略条件运算符

    查询编号为1角色所在书籍可以这样写

    >>> Book.objects.get(role__id=1)
    <Book: 射雕英雄传>
    

    根据一方条件查多方

    语法格式

    多方有对应关系的字段名__一方字段名__查询条件=值
    

    查询“雪山飞狐所有角色”

    >>> Role.objects.filter(r_book__b_title__exact="雪山飞狐")
    <QuerySet [<Role: 胡斐>, <Role: 苗若兰>, <Role: 程灵素>, <Role: 袁紫衣>]>
    

    查询阅读量大于30的书籍角色

    >>> Role.objects.filter(r_book__b_read__gt=30)
    <QuerySet [<Role: 乔峰>, <Role: 段誉>, <Role: 虚竹>, <Role: 王语嫣>, <Role: 胡斐>, <Role: 苗若兰>, <Role: 程灵素>, <Role: 袁紫衣>]>
    

    当查询条件是等于的时候可以省略条件运算符

    查询“雪山飞狐所有角色”可以这样写

    >>> Role.objects.filter(r_book__b_title="雪山飞狐")
    <QuerySet [<Role: 胡斐>, <Role: 苗若兰>, <Role: 程灵素>, <Role: 袁紫衣>]>
    

    删除数据使用查询结果对象的 delete 方法

    语法格式

    查询结果对象.delete()
    

    删除阅读量小于20的书

    >>> Book.objects.filter(b_read__lt=20).delete()
    (6, {'book.Role': 5, 'book.Book': 1})
    

    一般删除数据只使用逻辑删除,即修改 is_delete 字段为 True

    修改数据有两种方式

    1. save

    获得 单个模型类 对象,修改数据后使用save保存

    >>> role = Role.objects.get(id__exact=18)
    >>> role.r_name = "齐天大圣"
    >>> role.save()
    

    2. update

    获得 查询集 对象,使用 update 方法修改数据,修改后会返回被影响数据条数

    修改 id 大于15的角色名字为 “不知名人士”

    >>> Role.objects.filter(id__gt=15).update(r_name="不知名人士")
    4
    
  • 相关阅读:
    stm8s103 EEPROM烧程序时能否保留
    NEC芯片特别说明
    pic中断特别说明
    删除排序链表中的重复元素 II
    被围绕的区域
    计数二进制子串
    简单工厂模式
    打家劫舍 II
    打家劫舍
    相同的树
  • 原文地址:https://www.cnblogs.com/mxuanli/p/9962466.html
Copyright © 2020-2023  润新知