ORM查询

单表查询之下划线

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in models.Tb1.objects.filter(name__contains="ven")  # 获取name字段包含"ven"的models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感models.Tb1.objects.filter(id__range=[1, 3])      # id范围是1到3的,等价于SQL的bettwen and类似的还有:startswith,istartswith, endswith, iendswith date字段还可以:models.Class.objects.filter(first_day__year=2017)

#获取id大于1且小于10的值
print(models.Book.objects.filter(id__lt=10,id__gt=1))
# 查询 id 在 [1, 4, 5, 7]中的结果
print(models.Book.objects.filter(id__in=[1,4,5,7]))
# contains 字段包含指定值的
print(models.Book.objects.filter(title__contains="小单"))
# icontains 忽略大小写包含指定值
print(models.Book.objects.filter(title__icontains="NI"))
# 判断id值在 哪个区间的 SQL语句中的between and  1<= <=3
print(models.Book.objects.filter(id__range=[1,3]))
# 日期和时间字段还可以有以下写法
ret = models.Person.objects.filter(birthday__year=2000)
ret = models.Person.objects.filter(birthday__year=2000, birthday__month=5)

跨表查询操作

 

基于对象查询(子查询)


                   按字段(publish)    一对多   book  ----------------->  publish                  <----------------                    book_set.all()

 正向查询按字段:
    查询python这本书籍的出版社的邮箱
    python=models.Book.objects.filter(title="python").first()
    print(python.publish.email)
    反向查询按     表名小写_set.all()
    苹果出版社出版的书籍名称
    publish_obj=models.Publish.objects.filter(name="苹果出版社").first()
    for obj in publish_obj.book_set.all():
        print(obj.title)

                   按字段(authors.all())    多对多   book  ----------------------->  author                  <----------------

                  book_set.all()
    查询python作者的年龄
    python = models.Book.objects.filter(title="python").first()
    for author in python.authors.all():
        print(author.name ,author.age)

    查询alex出版过的书籍名称

    alex=models.Author.objects.filter(name="alex").first()
    for book in alex.book_set.all():
        print(book.title)


                     按字段 authorDetail    一对一   author  ----------------------->  authordetail                   <----------------                     按表名  author

    查询alex的手机号
    alex=models.Author.objects.filter(name=‘alex‘).first()
    print(alex.authorDetail.telephone)
    查询家在山东的作者名字
    ad_list=models.AuthorDetail.objects.filter(addr="shandong")
    for ad in ad_list:
        print(ad.author.name)
    对应的sql:
     select publish_id from Book where title="python"
     select email from Publish where nid =   1

基于queryset和__查询(join查询)

正向查询:按字段  反向查询:表名小写

查询python这本书籍的出版社的邮箱ret=models.Book.objects.filter(title="python").values("publish__email")print(ret.query)

select publish.email from Book left join Publish on book.publish_id=publish.nid where book.title="python"

苹果出版社出版的书籍名称方式1:ret1 = models.Publish.objects.filter(name="苹果出版社").values("book__title")print("111111111====>", ret1.query)# 方式2:ret2 = models.Book.objects.filter(publish__name="苹果出版社").values("title")print("2222222222====>", ret2.query)

查询alex的手机号方式1:ret = models.Author.objects.filter(name="alex").values("authorDetail__telephone")

方式2:models.AuthorDetail.objects.filter(author__name="alex").values("telephone")

查询手机号以151开头的作者出版过的书籍名称以及书籍对应的出版社名称

ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values(‘title‘, "publish__name")print(ret.query)

 

聚合查询

aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。用到的内置函数:from django.db.models import Avg, Sum, Max, Min, Countfrom django.db.models import Avg, Sum, Max, Min, Countbook_obj=models.Book.objects.all()print(book_obj.aggregate(Max("price")))  #{‘price__max‘: Decimal(‘9999.99‘)}#指定一个名称print(book_obj.aggregate(max_price=Max("price"))) #{‘max_price‘: Decimal(‘9999.99‘)}#生成多个聚合print(book_obj.aggregate(Max("price"),Min("price"),Avg("price"))) #{‘price__max‘: Decimal(‘9999.99‘), ‘price__min‘: Decimal(‘10.00‘), ‘price__avg‘: 1507.141429}

分组查询

1.和sql对比:    1.models.Employee Employee相当于sql中的from 后面的表名    2.annotate前面的values值相当于group by的字段    3.(a=Avg("salary"))里面如是跨表查询就需要使用双下划线,正查就字段__另一张表的字段,反查就另一张表明__字段    4.annotate后面的values 是select的字段    对应格式:select __ from ___ inner join ————  on ... group by  ____2.关键点:    1.queryset对象.annotate()  annotate前面是queryset对象    2.annotate进行分组统计,按前面select的字段进行group by    3.annotate()返回值依然是queryset对象,增加了分组统计之后的键值对

1.ORM中values或者values_list 里面写什么字段,就相当于select 什么字段
 ORM分组查询 每个部门名称及部门的平均年龄
ret = models.Employee.objects.all().values("dept", "age")
SQL语句
"""
SELECT `employee`.`dept`, `employee`.`age` FROM `employee` LIMIT 21; args=()
"""
2.ORM中 annotate 前面是什么就按照什么分组
from django.db.models import Avg
ret = models.Employee.objects.values("province").annotate(a=Avg("salary")).values("province", "a")
相当于:
SELECT `employee`.`province`, AVG(`employee`.`salary`) AS `a` FROM `employee` GROUP BY `employee`.`province` ORDER BY NULL LIMIT 21; args=()
print("分组查询".center(80, "*"))
3. ORM跨表分组查询,queryset对象跨表查询时使用双下划线
ret = models.Person.objects.values("dept_id").annotate(a=Avg("salary")).values("dept__name", "a")
反向:
"""
SELECT `dept`.`name`, AVG(`person`.`salary`) AS `a` FROM `person` INNER JOIN `dept` ON (`person`.`dept_id` = `dept`.`id`) GROUP BY `person`.`dept_id`, `dept`.`name` ORDER BY NULL LIMIT 21; args=()
"""
4.查询每一个部门的名称和人数
#正向查询:
models.emp.objects.values("dept_id").annotate(c=Count("name")).values("dept__name","c")
#反向查询
models.dep.objects.values("name").annotate(c=Count("emp__name")).values("name","c")
SQL: select dep_name Count(emp.name) from emp inner join dep on  .... group by dep_id

5.查询每一个作者的名字及出版过的书籍的最高价
models.Author.objects.values(‘id‘).annotate(c=Max(‘book__price‘)).values("name","c")
##多对多的关系,在sql中跨了多张表
select __ from author inner join book_authors on .... inner join ... group by author.name
6.查询每一本书作者的个数
models.Book.objects.values("id").annotate(c=Count("authors__name")).values("title","c")
ret=models.Book.objects.all().annotate(author_num=Count("author"))
for book in ret:
    print("书名:{},作者数量:{}".format(book.title, book.author_num))
#查询每一个分类的名称及对应的文章数 models.Category.objects.values("id").annotate(c=Count("article__title")).values("title","c") 7.统计不止一个作者的图书(过滤完后显示) models.Book.objects.values("title").annotate(c=Count("authors__name")).filter(c__gt=1).values(‘name‘,"c") 8.查询各个作者出的书的总价格 ret = models.Author.objects.all().annotate(price_sum=Sum("books__price")) for i in ret: print(i, i.name, i.price_sum)

extra  --> 在执行ORM查询的时候执行额外的SQL语句

# 查询person表,判断每个人的工资是否大于2000
ret = models.Person.objects.all().extra(
    select={"gt": "salary > 2000"}
)
相当于:
SELECT (salary > 2000) AS `gt`, `person`.`id`, `person`.`name`, `person`.`salary`, `person`.`dept_id` FROM `person` LIMIT 21; args=()

直接执行原生的SQL语句,类似pymysql的用法
from django.db import connection
cursor = connection.cursor()  # 获取光标,等待执行SQL语句
cursor.execute("""SELECT * from person where id = %s""", [1])
row = cursor.fetchone()
print(row)
                   F查询和Q查询             F查询    

要对两个字段的值做比较,Django 提供 F() 来做这样的比较。
F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
1.查询评论数大于收藏数的书籍
from django.db.models import F
models.Book.objects.filter(commnet_num__gt=F(‘keep_num‘))
2.Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
models.Book.objects.filter(commnet_num__lt=F(‘keep_num‘)*2)
3修改操作也可以使用F函数,比如将每一本书的价格提高30元
# 具体的对象没有update(),QuerySet对象才有update()方法
models.Book.objects.all().update(price=F("price")+30)
刷单 把每一本书的卖出数都乘以3
obj = models.Book.objects.first()
obj.maichu = 1000 * 3
obj.save()
4.给每一本书的书名后面加上 第一版
from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.update(title=Concat(F("title"), Value("第一版")))

    Q查询     

如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
from django.db.models import Q
1.查询 卖出数大于1000,并且 价格小于100的所有书
ret = models.Book.objects.filter(maichu__gt=1000, price__lt=100)
print(ret)
2.查询 卖出数大于1000,或者 价格小于100的所有书
ret = models.Book.objects.filter(Q(maichu__gt=1000) | Q(price__lt=100))
3. Q查询和字段查询同时存在时, 字段查询要放在Q查询的后面
ret = models.Book.objects.filter(Q(maichu__gt=1000) | Q(price__lt=100), title__contains="金老板")

Q().children查询

Q().children,通过字段字符串查询
        q=Q()
        ##查询出title字段中值为go的对象
        q.children.append(("title","go"))
        Book.objects.filter(q)
        Out[11]: <QuerySet [<Book: go>]>
        ##查询出title字段中值含有g的对象
        q.children.append(("title__contains","g"))
        Book.objects.filter(q)
        Out[13]: <QuerySet [<Book: go>]>
        q=Q()  #不同的字段之间的关系默认为and
        q.children.append(("title__contains","g"))
        q.children.append(("price",100))
        Book.objects.filter(q)
        Out[17]: <QuerySet []>
        q=Q()
        q.connector="or"  #不同的字段之间的关系更改为or
        q.children.append(("title__contains","g"))
        q.children.append(("price",100))
        Book.objects.filter(q)
        Out[22]: <QuerySet [<Book: go>]>

原文地址:https://www.cnblogs.com/fengbo123/p/10498472.html

时间: 2024-10-08 20:16:44

ORM查询的相关文章

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

Django 第十课 4.【ORM查询操作】

#查询 1:exact:在底层会被翻译成 '=' article = Article.objects.filter(title__exact='hello') 2:iexact:在底层被翻译成 'LIKE' article = Article.objects.filter(title__iexact='hello') * LIKE 和 = :大部分情况下都是等价的,只有少数情况下是不等价的. * exact和iexact:他们的区别其实就是LIKE和=的区别,因为exact会被翻译成=,而iex

065:ORM查询条件详解-gt、gte、lt和lte

ORM查询条件详解-gt.gte.lt和lte: 1.gt:某个 field 的值要大于给定的值.示例代码如下: articles = Article.objects.filter(id__gt=3) 以上代码的意思是将所有 id 大于4的文章全部都找出来.将翻译成以下 SQL 语句: SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id` FROM `article` WHER

Django—— ORM查询(sql优化)优化了解,Django(元信息)元类建索引

Django(元信息)元类建索引 索引:索引的一个主要目的就是加快检索表中数据,索引是经过某种算法优化过的,因而查找次数要少的多.可见,索引是用来定位的. class Book(models.Model) name = models.CharField(max_length=64) class Meta: # 自定义表名 db_table = 'table_name' # 联合索引: 索引的一个主要目的就是加快检索表中数据 index_together = ('tag1', 'tag2') #

ORM查询相关补充

自己没有记住的一点小知识(ORM查询相关) 一.多对多的正反向查询 class Class(models.Model): name = models.CharField(max_length=32,verbose_name="班级名") course = models.CharField(verbose_name="课程",max_length=32) def __str__(self): return self.name class Teacher(models.

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_SETTING

django模型层 、 ORM查询

模型层 ORM查询 单表查询 前期准备工作需求: 如何只单独测试django中的某一个py文件 如何书写测试脚本 如何使用: 在任意一个py文件中书写以下代码 应用下的tests 或者自己新建一个 import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings") import django django.se

Git.Framework 框架随手记--ORM查询返回实体对象

使用ORM有一个优势,可以通过某种机制将数据库中的数据转化为自己想要的对象形式数据.本章记录一下如何使用Git.Framework返回实体对象 一. Git.Framework 中提供的方法 在Git.Framework中有七个方法可以返回实体对象,先简答的看看这里的方法描述 (1) T GetSingle(int id); (2) T GetSingle(object value); (3) T GetSingle(T entity); (4) V GetSingle<V>(T entity