django3——查询语句

查询集

  • 查询集:表示从数据库中获取的模型对象集合
    • 管理器上调用过滤器方法会返回查询集
    • 查询集可以含有0个、一个或多个过滤器
  • 过滤器:基于所给的参数限制查询的结果
  • 提示:从sql的角度,查询集和select语句等价,过滤器像where和limit子句
  • 返回列表的过滤器如下:
    • all():返回所有的数据
    • filter():返回满足条件的数据
    • exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字
    • order_by():返回排序后的数据
  • 返回单个对象的过滤器如下:
    • get():返回单个满足条件的对象
      • 如果未找到会引发"模型类.DoesNotExist"异常
      • 如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常
    • count():返回当前查询的总条数
    • aggregate():聚合
    • exists():判断查询集中是否有数据,如果有则返回True,没有则返回False
查询集的两个特点
    1、惰性执行: 创建查询集不会访问数据库,直到在模板中调用数据时,才会访问数据库
  • 调用数据的情况包括迭代、序列化、与if合用
    2、缓存:查询集的结果被存下来之后,再次查询相同数据时会使用之前缓存的数据

基础条件查询
    • 查询所有
    bookInfos = BookInfo.book.all()
    • 1、查询id=1 的书本
    bookInfos = BookInfo.book.filter(id__exact=1)
    • 2、查询包含'湖'的书籍
    bookInfos = BookInfo.book.filter(name__contains='湖')
    • 3、查询义'部'结尾的书籍
    bookInfos = BookInfo.book.filter(name__endswith='部')
    • 4、 查询书籍名不能为空
    bookInfos = BookInfo.book.filter(name__isnull=False)
    • 5、查询编号为2或4的书籍
    bookInfos = BookInfo.book.filter(pk__in=[2,4])
    • 6、查询编号大于2的书籍
     gt、gte、lt、lte: 大于、大于等于、小于、小于等于
     bookInfos = BookInfo.book.filter(id__gt=2)
    •  7、查询ID不等于3的书籍(exclue)
    bookInfos = BookInfo.book.exclude(id=3)
    •  8 查询1980年出版的书籍
    year、month、day、week_day、hour、minute、second: 对日期时间类型的属性进行运算
    bookInfos = BookInfo.book.filter(pub_date__year='1980')
    • 9、查询1990年1月1日后发表的书籍
      from datetime import date
     bookInfos = BookInfo.book.filter(pub_date__gt=date(1990,1,1))
    或者
    bookInfos = BookInfo.book.filter(pub_date__gt=‘1990-01-01’)
    F方法与Q方法
    导入函数
    from django.db.models import F,Q

    F('属性名')
    1、查询阅读量大于评论量的书籍
    bookInfos = BookInfo.books.filter(readcount__gt=F('commentcount'))
    2、查询阅读量大于2倍评论量的书籍:F支持乘法运算
    bookInfos = BookInfo.books.filter(readcount__gt=F('commentcount')*2)
    Q对象查询需求
    from django.db.models import Q

    Q(模型属性1__条件运算符=值) | Q(模型属性2__条件运算符=值)
    1.查询阅读量大于20,或编号小于3的图书
      bookInfos = BookInfo.books.filter(Q(readcount__gt=20) | Q(id__lt=3))
    2.查询编号不等于3的书籍(Q对象前可以使用〜操作符,表示非
    bookInfos = BookInfo.books.filter(~Q(id=3))
      或
      bookInfos = BookInfo.books.exclude(id=3)

    聚合函数

    • 使用aggregate()过滤器调用聚合函数,返回单个对象
    • 聚合函数包括AvgMaxMinSum, ,Count
      • 使用Count时,不需要一般aggregate()过滤器,直接调用即可
    • 定义被在django.db.models
    from django.db.models import Sum

    def bookList(request):
        # 查询编号不等于3的书籍
        bookInfos = BookInfo.books.filter(~Q(id=3))
        # 统计总的阅读量
        readcount = BookInfo.books.aggregate(Sum('readcount'))

        # 构造上下文
        context = {'booklist':bookInfos,'readcount':readcount}
        return render(request, 'Book/booklist.html', context)

    关联查询

    基础关联查询
    # 1.查询编号为1的图书中所有人物信息
    # 2.查询编号为1的英雄出自的书籍
    • 1.查询编号为1的图书中所有人物信息
      • 通过书找关联的人
        # 先查编号为1的书
        book = BookInfo.books.get(pk=1)
        # 再通过关联查询到编号为1的书里面的任务信息
        peopleInfos = book.peopleinfo_set.all()
    • 2.查询编号为1的英雄出自的书籍
      • 通过人找关联的书
        # 先查编号为1的人物
        people = PeopleInfo.objects.get(pk=1)
        # 再通过关联查询编号为1的人物对应的书
        bookInfo = people.book
    内连接查询
    • 语法如下 :
        关联模型类名小写__属性名__运算符=值
      • 结果和sql中的inner join相同(内连接)
    • 需求
      # 1.查询书名为"天龙八部"的所有人物信息
      # 2.查询书籍中人物的描述包含"降龙"的书籍
    • 1.查询书名为"天龙八部"的所有人物信息(peopleInfo)
    • 通过书找关联的人
      • # 原始内连接sql语句:

    select p.name, b.name from peopleinfo as p inner join bookinfo as b on p.book_id = b.id where b.name = "天龙八部"

    peopleInfos = PeopleInfo.objects.filter(book__name='天龙八部')
    bookInfos = BookInfo.books.filter(peopleinfo__description__contains='降龙')

    • 2.查询书籍中人物的描述包含"降龙"的书籍
      • 通过人找关联的书
    自关联查询


    ### 如何在Django项目中执行原生MySQL查询语句 #### 使用 `django.db.connection` 通过导入`from django.db import connection`,可以直接访问数据库连接并执行任意SQL命令。此方式适用于需要完全控制SQL的情况。 ```python from django.db import connection def my_custom_sql(): with connection.cursor() as cursor: cursor.execute("SELECT * FROM some_table WHERE condition=%s", [value]) rows = cursor.fetchall() return rows ``` 这种方式提供了极大的灵活性,可以执行任何有效的SQL语句[^1]。 #### 使用 Django ORM 的 `raw()` 方法 对于那些希望保持一定程度上抽象但仍需编写自定义SQL的人来说,Django提供了一个名为`raw()`的方法。该方法允许传递一条完整的SQL查询给模型类,并返回一个原始查询集对象。 ```python Person.objects.raw('SELECT id, first_name, last_name FROM myapp_person') ``` 这种方法仍然利用了Django的模型机制,在获取数据的同时也享受到了一些框架带来的便利之处。 #### 注意事项 - 当构建含有参数化的查询时,请始终使用列表形式传入参数而不是直接拼接字符串,以防SQL注入攻击。 - 对于复杂的查询尤其是涉及多个表联结的操作,建议优先考虑使用Django内置的QuerySet API完成;只有当确实无法满足需求时才转向原生SQL。 - 如果涉及到批量更新或删除操作,则应该确保这些更改是在事务内进行以保障数据一致性。 #### 批量操作与事务管理 为了保证数据的一致性和完整性,在处理大量记录修改或者多条相互依赖的数据变更时应当采用事务管理: ```python from django.db import transaction with transaction.atomic(): # Perform database operations here... ``` 这样即使中间发生错误也能回滚到初始状态而不影响其他正常运行的部分。 #### 复杂查询与聚合 有时候业务逻辑可能要求实现较为复杂的查询条件或是统计分析功能,这时除了基本的选择外还需要加入分组(Group By)、汇总(Summary Functions)等功能支持。此时同样可以通过编写更高级别的SQL来达成目标。 #### 结合ORM使用原生SQL 尽管已经能够独立写出想要执行的具体指令,但在某些场景下混合运用两者或许会带来更好的开发体验——既保留了原有优势又简化了一些重复劳动的工作量。比如可以在视图函数里先调用一次标准API拿到初步筛选后的结果集合然后再针对这部分子集做进一步加工处理。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值