django -- ORM查询(二)

简介: django -- ORM查询

聚合查询


在sql语句中,我们知道聚合语句,比如查询最大值,最小值,平均值等等。在ORM中,使用aggregate()来进行聚合查询,首先需要导入

from django.db.models import Max, Min, Avg, Sum, Count

查询价格最大是多少

from django.db.models import Max, Min, Avg, Sum, Count
ret = models.Book.objects.aggregate(Max('price'))
print(ret)
ret = models.Book.objects.all().aggregate(Max('price'))
print(ret)

结果:

{'price__max': 66}
{'price__max': 66}

结果是一个字典格式,key为“字段_聚合名”,如果你看它不爽,你也可以自定义

from django.db.models import Max, Min, Avg, Sum, Count
ret = models.Book.objects.aggregate(最大值=Max('price'),最小值=Min('price'))
print(ret)

结果:

{'最大值': 66, '最小值': 22}

注意:如果你查询了多个,有些聚合你自己定义了名称,有些你没有定义名称,则没有定义名称的要放在前面(位置参数不能在关键字参数后面)


分组查询


先来看一下数据表关系

查询出每本书的作者

from django.db.models import Max, Min, Avg, Sum, Count
ret = models.Book.objects.annotate(num=Count('author'))
print(ret)

结果是QuerySet

<QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>]>

使用.values()获取所有

from django.db.models import Max, Min, Avg, Sum, Count
ret = models.Book.objects.annotate(num=Count('author')).values()
for i in ret:
    print(i)

结果:

{'id': 1, 'title': 'linux', 'price': 22, 'publisher_id': 2, 'num': 1}
{'id': 2, 'title': 'python入门到放弃', 'price': 55, 'publisher_id': 3, 'num': 0}
{'id': 3, 'title': 'java直接放弃', 'price': 22, 'publisher_id': 3, 'num': 1}
{'id': 4, 'title': 'go精通', 'price': 54, 'publisher_id': 1, 'num': 2}
{'id': 5, 'title': '一小时精通Django', 'price': 66, 'publisher_id': 3, 'num': 1}

可以在value里指定参数获取想要的字段

from django.db.models import Max, Min, Avg, Sum, Count
ret = models.Book.objects.annotate(num=Count('author')).values('title','num')
for i in ret:
    print(i)

结果:

num对应的值就是这本书作者的个数

{'title': 'linux', 'num': 1}
{'title': 'python入门到放弃', 'num': 0}
{'title': 'java直接放弃', 'num': 1}
{'title': 'go精通', 'num': 2}
{'title': '一小时精通Django', 'num': 1}

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

from django.db.models import Max, Min, Avg, Sum, Count
ret = models.Book.objects.values('publisher_id').annotate(min_num=Min('price'))
for i in ret:
    print(i)

结果:

{'publisher_id': 1, 'min_num': 54}
{'publisher_id': 2, 'min_num': 22}
{'publisher_id': 3, 'min_num': 22}

因为不分组的结果

from django.db.models import Max, Min, Avg, Sum, Count
ret = models.Book.objects.values('publisher_id')
for i in ret:
    print(i)

结果:

{'publisher_id': 1}
{'publisher_id': 2}
{'publisher_id': 3}
{'publisher_id': 3}
{'publisher_id': 3}

统计不止一个作者的图书

ret = models.Book.objects.annotate(num=Count('author')).filter(num__gt=1).values()
for i in ret:
    print(i)

结果:

{'id': 4, 'title': 'go精通', 'price': 54, 'publisher_id': 1, 'num': 2}

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


F查询


在之前的查询中,我们都是拿某个字段对一个固定的值做比较,如果想用字段和字段做比较,就要用到F查询了,先来看下数据表里的数据

需求,查出所有num大于money的

from django.db.models import F
ret = models.Book.objects.filter(num__gt=F('money')).values()
for i in ret:
    print(i)

结果:

{'id': 1, 'title': 'linux', 'price': 22, 'publisher_id': 2, 'money': 23, 'num': 65}
{'id': 4, 'title': 'go精通', 'price': 54, 'publisher_id': 1, 'money': 33, 'num': 88}
{'id': 5, 'title': '一小时精通Django', 'price': 66, 'publisher_id': 3, 'money': 44, 'num': 99}

需求:给每个num的值*2

之前的都是对某一条数据更新的,如

ret = models.Book.objects.get(id=2)
ret.num=24
ret.save()

上面的这种写法要进行save(),而且要写更新的具体数值

使用update更新

ret = models.Book.objects.filter(id=2).update(num=50)

update就不需要save

ret = models.Book.objects.update(num=50)  # 对所有的数据更新

这两种写法都满足不了我们的需求,我们用F来实现,下面两种结果是一样的

from django.db.models import F
ret = models.Book.objects.update(num=F('num')*2)
ret = models.Book.objects.all().update(num=F('num')*2)

需求:在所有书名后面加上(测试)

ret = models.Book.objects.update(title=Concat(F("title"), Value("("), Value("测试"), Value(")")))

不需要()

ret = models.Book.objects.update(title=Concat(F("title"), Value("测试")))


Q查询


之前我们所有进行的查询都是and关系的,如果要使用or关系的查询,就要用Q查询了。继续看数据表数据

需求:查询id小于3并且大于等于6的

from django.db.models import Q
ret = models.Author.objects.filter(Q(id__lt=3) | Q(id__gte=6)).values()
for i in ret:
    print(i)

结果:管道符( | )表示或的关系

{'id': 1, 'name': '孙悟空'}
{'id': 2, 'name': '猪八戒'}
{'id': 6, 'name': '蜘蛛精'}
{'id': 7, 'name': '女儿国'}
{'id': 8, 'name': '紫霞仙子'}

&表示并且的关系

from django.db.models import Q
ret = models.Author.objects.filter(Q(id__lt=7) & Q(id__gte=6)).values()
for i in ret:
    print(i)

结果:

{'id': 6, 'name': '蜘蛛精'}

~表示取反

from django.db.models import Q
ret = models.Author.objects.filter(~Q(id__lt=7) & Q(id__gte=6)).values()
for i in ret:
    print(i)

结果:

{'id': 7, 'name': '女儿国'}
{'id': 8, 'name': '紫霞仙子'}


事务


事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行。所以,应该把它们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。

针对上面的描述可以看出,事务的提出主要是为了解决并发情况下保持数据一致性的问题。

事务具有以下4个基本特征。

  • Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
  • Consistency(一致性):只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。
  • Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
  • Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。
import os
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_project.settings")
    import django
    django.setup()
    from appTest01 import models
    try:
        from django.db import transaction
        with transaction.atomic():
            这里写要执行的ORM语句
    except Exception as e:
        print(str(e))

 


相关文章
|
2月前
|
SQL Go 数据库
【速存】深入理解Django ORM:编写高效的数据库查询
【速存】深入理解Django ORM:编写高效的数据库查询
62 0
|
2月前
|
SQL 前端开发 Python
基于python-django的neo4j人民的名义关系图谱查询系统
基于python-django的neo4j人民的名义关系图谱查询系统
35 0
|
4月前
|
数据管理 数据挖掘 调度
Django后端架构开发:URLconf到ORM深度剖析
Django后端架构开发:URLconf到ORM深度剖析
58 1
|
4月前
|
数据库 Python
Django ORM
【8月更文挑战第23天】
49 4
|
4月前
|
API 数据库 开发者
【独家揭秘】Django ORM高手秘籍:如何玩转数据模型与数据库交互的艺术?
【8月更文挑战第31天】本文通过具体示例详细介绍了Django ORM的使用方法,包括数据模型设计与数据库操作的最佳实践。从创建应用和定义模型开始,逐步演示了查询、创建、更新和删除数据的全过程,并展示了关联查询与过滤的技巧,帮助开发者更高效地利用Django ORM构建和维护Web应用。通过这些基础概念和实践技巧,读者可以更好地掌握Django ORM,提升开发效率。
43 0
|
4月前
|
SQL Go 数据库
Django入门到放弃之ORM多表操作
Django入门到放弃之ORM多表操作
|
4月前
|
SQL 关系型数据库 MySQL
Django入门到放弃之ORM单表操作
Django入门到放弃之ORM单表操作
|
5月前
|
SQL 数据库 Python
Django框架数据库ORM查询操作(6)
【7月更文挑战第6天】```markdown Django ORM常用数据库操作:1) 查询所有数据2) 根据ID查询 3) 精确查询 4) 分页排序
79 1
|
6月前
|
SQL 缓存 数据库
Django中ORM性能调优
【6月更文挑战第19天】 1. **索引优化**:使用`db_index=True`为模型字段创建索引,提升查询速度。 2. **批量操作**:批量创建和更新,减少数据库交互。 3. **查询优化**:利用`select_related`和`prefetch_related`减少查询次数。 4. **缓存**:使用内置缓存或Redis减少数据库访问。 5. **异步任务**:用Celery处理耗时操作,提高响应速度。 6. **数据库连接池**:管理连接,减少创建和销毁开销。 7. **SQL直接操作**:在必要时用原生SQL,避免ORM性能瓶颈。 8. **分页查询**:减少数据传输,改善用
85 10
|
6月前
|
JSON 数据库 数据格式
使用 Django Q 对象构建复杂查询条件
通过本文示例,我们展示了如何使用Django的Q对象来构建复杂的查询条件,以及如何实现分页功能。Q对象的强大之处在于它能够轻松地组合多个查询条件,支持“与”、“或”关系,极大地提高了查询的灵活性和可读性。希望本文对你在实际项目中使用Django ORM构建复杂查询有所帮助。