Djangoo框架5 orm查询

目录

  • Djangoo框架5 orm查询

    • 一.单表查询
    • 二.多表查询
    • 三.聚合查询
    • 四.分组查询
    • 五.F与Q查询

Djangoo框架5 orm查询


一.单表查询

1.必会的16条查询语句

? 如何只单独测试django中的某一个py文件,如何书写测试脚本

? 在任意一个py文件中书写代码:
? 应用下的tests或者自己去新建一个

import os

if __name__ == "__mian__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
    from app01 import models
    models.Movie.object.all()

创建movie表

class Movie(models.Model):
    title = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish_time = models.DateField()  # 年月日
    # publish_time = models.DateTimField()  # 年月日时分秒

    def __str__(self):
        return self.title

auto_now: 每次修改数据的时候 都会自动将最新的封信时间记录下来

auto_now_add: 只会在创建数据的时候将创建时间自动记录下来 之后就不会再自动改变

16条查询语句

1.create()
    # 返回值就是当前被创建的对象的本身
    # 日期可以手动给
    models.Movie.objects.create(title='西游记', price=989.32, publish_time='2016-1-4')
    # 还可以直接传日期对象
    from datetime import date

    ctime = date.today()
    # models.Movie.objects.create(title='虎虎虎', price=989.32, publish_time=ctime)

2.all()
    res = models.Movie.objects.all()
    print(res)

3.filter()
    # 返回的也是queryset对象
     res = models.Movie.objects.filter(id=1)
     res = models.Movie.objects.filter(pk=1)  # pk指代的就是当前表的主键字段名  自动查找非常方便
    res = models.Movie.objects.filter(pk=1,title='python入门')  # 括号内可以放多个条件默认是AND关系
    print(res)
    # 只要是queryset对象  就可以通过 点query 的方式查看到获取到当前对象内部sql语句
    print(res.query)

4.update()  更新数据      返回值是受影响的行数
# res = models.Movie.objects.filter(pk=1).update(title='虎虎虎')
res = models.Movie.objects.filter(pk=1).update(title='虎虎虎2', price=666)
print(res)

5.delete()  删除数据    返回值(1, {'app01.Movie': 1})  受影响的表及行数
  res = models.Movie.objects.filter(pk=3).delete()
     print(res) 

6.first()   数据对象        取第一个元素对象
 res = models.Movie.objects.filter().first()
     print(res)
   虎虎虎2

7.last() 数据对象          取最后一个元素对象
     res = models.Movie.objects.last()
     print(res)
西游记

8.get() 直接获取对象本身  # 不推荐使用
当查询条件不存在的时候直接报错
     res = models.Movie.objects.get(pk=1)
     print(res)
     print(res.title)
     print(res.price)
     res = models.Movie.objects.get(pk=1000)
     res = models.Movie.objects.filter(pk=1000)
     print(res)

9.values() QuerySet对象  [{},{},{}]     获取指定字段对的数据    列表套字典
     res = models.Movie.objects.values('title','publish_time')
     print(res)
     print(res.query)

<QuerySet [{'title': '虎虎虎2', 'publish_time': datetime.date(2020, 1, 8)}, {'title': '西游记', 'publish_time': datetime.date(2016, 1, 4)}]>
SELECT `app01_movie`.`title`, `app01_movie`.`publish_time` FROM `app01_movie`

10.values_list()    QuerySet对象  [(),(),()]  获取指定字段对的数据 列表套元组
   res = models.Movie.objects.values_list('title','price')
   print(res)

<QuerySet [('虎虎虎2', Decimal('666.00')), ('西游记', Decimal('989.32'))]>

11.order_by()   按照指定字段排序
     res = models.Movie.objects.order_by('price')  # 默认是升序
     res = models.Movie.objects.order_by('-price')  # 减号就是降序
     print(res)

12.count()  统计数据条数
  res = models.Movie.objects.count()
  print(res)

13.exclude()    排除什么什么之外  少选条件
     res = models.Movie.objects.exclude(pk=1)
     print(res)

14.exists()     返回的是布尔值  判断前面的对象是否有数据  了解即可
     res = models.Movie.objects.filter(pk=1000).exists()
     print(res)
    False

15.reverse()    反转
     res = models.Movie.objects.order_by('price').reverse()
     print(res)

16.distinct()   去重:去重的前提 必须是由完全一样的数据的才可以    要注意包括id
     res = models.Movie.objects.values('title','price').distinct()
     print(res)

2神奇的双下划线查询

? 1.查询价格大于200的电影

res = models.Movie.objects.filter(price__gt=200)

? 2.查询价格小于500的电影

res = models.Movie.objects.filter(price__lt=500)

? 3.查询价格大于等于88的电影

res = models.Movie.objects.filter(price__gte=876.23)

? 4.查询价格小于等于88的电影

res = models.Movie.objects.filter(price__lte=500)

? 5.查询价格是123 或666 或者888的电影

res = models.Movie.objects.filter(price__in=[123,666,876])

? 6.查询价格在200到900之间的电影 顾头也顾尾

res = models.Movie.objects.filter(price__range=(200,900))

? 7.查询电影名中包含字母p的电影

res = models.Movie.objects.filter(title__contains=‘p‘) 默认是区分大小写

res = models.Movie.objects.filter(title__icontains=‘p‘) i忽略大小写

? 8.查询2014年出版的电影

res = models.Movie.objects.filter(publish_time__year=2014)

? 9.查询是1月份出版的电影

res = models.Movie.objects.filter(publish_time__month=1)

二.多表查询

1.图书管理系统表的创建

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_time = models.DateField(auto_now_add=True)  # 该字段新增数据自动添加 无需考虑

    # 出版社   一对多    外键字段建在多的一方
    publish = models.ForeignKey(to='Publish')
    # 作者     多对多    外键字段建在任意一方均可 推荐你建在查询频率较高的表
    authors = models.ManyToManyField(to='Author')

    # 库存数
    kucun = models.BigIntegerField(default=1000)
    # 卖出数
    maichu = models.BigIntegerField(default=1000)

    def __str__(self):
        return self.title

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    # 作者详情   一对一    外键字段建在任意一方均可 推荐你建在查询频率较高的表
    author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=32)

2.外键字段的增删改查

? 一对多 publish

# 1.增  直接写实际的表字段 publish_id
# models.Book.objects.create(title='三国演义',price=123.23,publish_id=2)
# 2.增
# publish_obj = models.Publish.objects.get(pk=1)
# models.Book.objects.create(title='梦想的声音',price=66.66,publish=publish_obj)

# 查

# 改
# models.Book.objects.filter(pk=1).update(publish_id=3)
# publish_obj = models.Publish.objects.get(pk=4)
# models.Book.objects.filter(pk=1).update(publish=publish_obj)

# 删
"""
外键字段在1.X版本中默认就是级联更新级联删除的
2.X版本中 则需要你自己手动指定
"""

? 多对多

1 给书籍绑定作者关系 add

# book_obj = models.Book.objects.filter(pk=1).first()

# 书籍和作者的关系是由第三张表决定 也就意味着你需要操作第三张表
# print(book_obj.authors)  # 书籍对象点虚拟字段authors就类似于已经跨到书籍和作者的第三张关系表中
# book_obj.authors.add(1)  # 给书籍绑定一个主键为1的作者
# book_obj.authors.add(2,3)

# author_obj = models.Author.objects.get(pk=1)
# author_obj1 = models.Author.objects.get(pk=3)
# book_obj.authors.add(author_obj)
# book_obj.authors.add(author_obj,author_obj1)

"""
add专门给第三张关系表添加数据
    括号内即可以传数字也可以传对象  并且都支持传多个
"""

2 移除书籍与作者的绑定关系 remove

# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.remove(2)
# book_obj.authors.remove(1,3)
# author_obj = models.Author.objects.get(pk=2)
# author_obj1 = models.Author.objects.get(pk=3)
# book_obj.authors.remove(author_obj)
# book_obj.authors.remove(author_obj,author_obj1)
"""
remove专门给第三张关系表移除数据
    括号内即可以传数字也可以传对象  并且都支持传多个
"""

3 修改书籍与作者的关系 set

book_obj = models.Book.objects.filter(pk=1).first()
# # book_obj.authors.set((3,))
# # book_obj.authors.set((2,3))
# author_obj = models.Author.objects.get(pk=2)
# author_obj1 = models.Author.objects.get(pk=3)
# # book_obj.authors.set((author_obj,))
# book_obj.authors.set([author_obj,author_obj1])

"""
set 修改书籍与作者的关系
    括号内支持传数字和对象 但是需要是可迭代对象
"""

4 清空书籍与作者关系

book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.clear()  # 去第三张表中清空书籍为1的所有数据
"""
clear()  清空关系
不需要任何的参数
"""

3.跨表查询

跨表查询方式

? 1.子查询 将一张表的查询结果当做另一张表的查询条件,正常解决问题的思路 分布操作

? 2.链表查询

? inner join

? left join

? right join

? union

在写sql语句或者orm语句的时候 一点一点地写

正反向的概念

? 正向:

? 跨表查询的时候,外键字段是否在当前数据对象中,如果在

查询另一张关系表 叫做正向

? 反向:

? 如果不在叫做反向

? 口诀:
? 正向查询按外键字段

? 反向查询按表名小写

a.基于对象的跨表查询

1.查询书籍pk为1的出版社名称

# book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.publish)
# print(book_obj.publish.name)
# print(book_obj.publish.addr)

2.查询书籍pk为2的所有作者的姓名

# book_obj = models.Book.objects.filter(pk=2).first()
# # print(book_obj.authors)  # app01.Author.None
# print(book_obj.authors.all())
# author_list = book_obj.authors.all()
# for author_obj in author_list:
#     print(author_obj.name)

3.查询作者pk为1的电话号码

# author_obj = models.Author.objects.filter(pk=1).first()
# print(author_obj.author_detail)
# print(author_obj.author_detail.phone)
# print(author_obj.author_detail.addr)

"""
正向查询的时候 当外键字段对应的数据可以有多个的时候需要加.all()
否则点外键字典即可获取到对应的数据对象
"""

4.查询出版社名称为东方出版社出版过的书籍

# publish_obj = models.Publish.objects.filter(name='东方出版社').first()
# print(publish_obj.book_set)  # app01.Book.None
# print(publish_obj.book_set.all())

5.查询作者为jason写过的书

# author_obj = models.Author.objects.filter(name='jason').first()
# print(author_obj.book_set)  # app01.Book.None
# print(author_obj.book_set.all())

6.查询手机号为120的作者姓名

# author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
# print(author_detail_obj.author)
# print(author_detail_obj.author.name)
# print(author_detail_obj.author.age)

"""
基于对象的反向查询 表名小写是否需要加_set.all()
一对多和多对多的时候需要加
一对一不需要
"""

b.基于双下划线的跨表查询(链表查询)

1.查询书籍pk为1的出版社名称

# 正向
# res = models.Book.objects.filter(pk=1).values('publish__name')  # 写外键字段 就意味着你已经在外键字段管理的那张表中
# print(res)
# 反向
# res = models.Publish.objects.filter(book__pk=1)  # 拿出版过pk为1的书籍对应的出版社
# res = models.Publish.objects.filter(book__pk=1).values('name')
# print(res)

2.查询书籍pk为1的作者姓名和年龄

# 正向
# res = models.Book.objects.filter(pk=1).values('title','authors__name','authors__age')
# print(res)
# 反向
# res = models.Author.objects.filter(book__pk=1)  # 拿出出版过书籍pk为1的作者
# res = models.Author.objects.filter(book__pk=1).values('name','age','book__title')
# print(res)

3.查询作者是jason的年龄和手机号

# 正向
# res = models.Author.objects.filter(name='jason').values('age','author_detail__phone')
# print(res)
# 反向
# res = models.AuthorDetail.objects.filter(author__name='jason')  # 拿到jason的个人详情
# res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__age')
# print(res)

# 查询书籍pk为的1的作者的手机号
# res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
# print(res)

# res = models.AuthorDetail.objects.filter(author__book__pk=1).values('phone')
# print(res)

"""
只要表之间有关系  你就可以通过正向的外键字段或者反向的表名小写 连续跨表操作
"""

三.聚合查询

from django.db.models import Max,Min,Avg,Count,Sum
res = models.Book.objects.aggregate(Avg("price"), Max("price"), Min("price"),Count("pk"),Sum('price'))

四.分组查询

1.统计每一本书的作者个数

# res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
# print(res)

2.统计出每个出版社卖的最便宜的书的价格

# res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price','book__title')
# print(res)

3.统计不止一个作者的图书

# res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title')
# print(res)

4.查询各个作者出的书的总价格

# res = models.Author.objects.annotate(price_sum=Sum('book__price')).values('name','price_sum')
# print(res)

5.如何按照表中的某一个指定字段分组

res = models.Book.objects.values('price').annotate()  就是以价格分组

五.F与Q查询

1.查询库存数大于卖出数的书籍

# res = models.Book.objects.filter(kucun__gt=F('maichu'))
# print(res)

# 2.将所有书的价格提高100
# res = models.Book.objects.update(price=F('price') + 100)
"""
帮你获取到表中某个字段对应的值
"""

2.Q能够改变查询的条件关系 and or not

# 1.查询书的名字是python入门或者价格是1000的书籍
# res = models.Book.objects.filter(title='python入门',price=1000)  # and关系
# res = models.Book.objects.filter(Q(title='python入门'),Q(price=1000))  # 逗号是and关系
# res = models.Book.objects.filter(Q(title='python入门')|Q(price=1000))  # |是or关系
# res = models.Book.objects.filter(~Q(title='python入门')|Q(price=1000))  # ~是not关系
# print(res.query)

# Q的高阶用法
# res = models.Book.objects.filter('title'='python入门')

    q = Q()
    q.connector = 'or'  # q对象默认也是and关系  可以通过connector改变or
    q.children.append(('title','python入门'))
    q.children.append(('price',1000))

    res = models.Book.objects.filter(q)
    print(res)

原文地址:https://www.cnblogs.com/godlover/p/12169005.html

时间: 2024-08-30 15:02:34

Djangoo框架5 orm查询的相关文章

[开源].NET数据库访问框架Chloe.ORM

前言 13年毕业之际,进入第一家公司实习,接触了 EntityFramework,当时就觉得这东西太牛了,访问数据库都可以做得这么轻松.优雅!毕竟那时还年轻,没见过世面.工作之前为了拿个实习机会混个工作证明,匆匆忙忙学了两个月的 C#,就这样,稀里糊涂的做了程序员,从此走上了一条不归路.那会也只知道 SqlHelper,DataTable.ORM?太高档上,没听说过.虽然在第一家公司只呆了两个月,但让我认识了 EntityFramework,从此也走上了 ORM 的不归路...纯纯的实体,增改删

Django框架05 /orm单表操作

目录 Django框架05 /orm单表操作 昨日内容回顾 今日内容 orm单表操作 对象关系映射(object relational mapping) 1.orm介绍 2.增: 3.时间问题 4.删 5.改 6.批量插入 -- bulk_create 7.查询api 8.基于双下划线的模糊查询 -- filter双下划线查询 9.总结 总结1 总结2 Django框架05 /orm单表操作 昨日内容回顾 模板相关 模板继承(母版继承) 1. 创建一个xx.html页面(作为母版,其他页面来继承

Django框架08 /聚合查询、分组、F查询和Q查询、执行原生sql、设置 sql_mode

目录 Django框架08 /聚合查询.分组.F查询和Q查询.执行原生sql.设置 sql_mode 1.聚合查询 2.分组 3.F查询和Q查询 4.执行原生sql(了解) 5.展示sql的 6.设置 sql_mode Django框架08 /聚合查询.分组.F查询和Q查询.执行原生sql.设置 sql_mode 1.聚合查询 aggregate(*args, **kwargs) aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典.键的名称是聚合值

Net框架下-ORM框架LLBLGen的简介(转载)

Net框架下-ORM框架LLBLGen的简介 http://www.cnblogs.com/huashanlin/archive/2015/02/12/4288522.html 官方网址:http://www.llblgen.com/

三大框架中模糊查询代码

js获取查询条件,并去后台查询 function queryByName(){                    //获取查询条件的用户名                    var queryName=$("#queryName").val();                    alert(queryName);                    //进行后台跳转                    window.location.href="<%=

TP框架中field查询字段

TP框架中field查询字段 不是fields 也不是files !!!! 不是fields 也不是files !!!! 不是fields 也不是files !!!! 不是fields 也不是files !!!! 不是fields 也不是files !!!! field

beego框架之orm模块

参考beego原文:http://beego.me/docs/mvc/model/orm.md#main.go beego ORM 是一个强大的 Go 语言 ORM 框架,orm模块主要是处理MVC中的M(models). 首先以bee工具创建一工程名为:beegoorm,修改的文件为 beegoorm/main.go 和 beegoorm/models/models.go(仅2个文件) beegoorm/models/models.go package models import ( "git

dajngo ORM查询中select_related的作用,博客主题的定制,从数据库中按照年月筛选时间

1.dajngo ORM查询中select_related的作用 select_related()方法一次性的把数据库关联的对象都查询出来放入对象中,再次查询时就不需要再连接数据库,节省了后面查询数据库的次数和时间.主要用于外键查询. blogobj = Blog.objects.filter(site=site).select_related('user').first() 2.博客主题的定制 将各个模块的css样式固定,然后通过.css文件导入,可以在数据里面设置.css文件的名字在模板中通

django知识之ORM查询

1. ORM字段 1. AutoField(primary_key=True)      -------->自增且主键 2. CharField(max_length=16)         --------->varchar类型(char类型可以自定义 类改写db_type) 3. IntegerField(null=True) --> 最大10位    -------->int类型(最大10位所以手机号码一般用char或者varchar类型) 4. DateField(auto