day54 django 分组查询

聚合查询

级联更新 级联删除 外键字段带来的约束
操作外键字段管理数据的时候
举例:书跟出版社是一对多关系,外键字段在书这。如果把出版社删了,所对应的书也会自动删除。如果把出版社主键更改了,所对应的书也会自动更新

聚合函数必须用来分组之后
没有分组其实默认整体就是一组

Max,Min.Sum,Avg,Count

1.关键字 aggregate
2.导入模块

from django.db.models import Max,Min.Sum,Avg,Count
只要数据库相关的功能,基本都是在django.db.models里面
如果不在,可能直接在django.db里面
'''聚合函数'''
    from django.db.models import Max,Min,Avg,Sum,Count

    #1.筛选出价格最高的书籍
    res=models.Book.objects.aggregate(mr=Max('price'))#mr是别名
    res=models.Book.objects.aggregate(Max('price'))
    print(res)

    #2.求书籍总价格
    res=models.Book.objects.aggregate(sm=Sum('price'))
    print(res)

    #3.求书籍平均价格
    res=models.Book.objects.aggregate(av=Avg('price'))
    print(res)

    #4.一起使用
  res=models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('price'),Avg('price'))
    print(res)

分组查询

​ mysql: group by
​ 什么时候需要分组:
​ 1.统计每个部门的平均薪资
​ 2.统计每个部门的男女比例

1.关键字:annotate
2.借助于聚合函数

from django.db.models import Max,Min.Sum,Avg,Count
django中models后面点什么,就按照什么分组
'''分组查询'''
    from django.db.models import Max,Min,Avg,Sum,Count
    #1.统计每一本的作者个数  书名和作者数量
    res=models.Book.objects.annotate(author_num=Count('author__id'))
  res=models.Book.objects.annotate(author_num=Count('author__id')).values('title','author_num')
    #< QuerySet[{'title': '西游记', 'author_num': 3}, {'title': '水浒传', 'author_num': 0}] >
    print(res)

    #2.统计出每个出版社卖的最便宜的书的价格  个人理解(values只能跟基表和分组名)
  res=models.Pbulish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
    #<QuerySet [{'name': '西方出版社', 'min_price': Decimal('555.00')}, {'name': '南方出版社', 'min_price': Decimal('666.00')}, {'name': '北方出版社', 'min_price': None}]>
    print(res)
    #可以按其他字段分组
  res=models.Pbulish.objects.values('pk').annotate(min_price=Min('book__price')).values('name','min_price')
    print(res)

    #3.统计不止一个作者的图书
    # 1.先拿书及对应作者书
    # 2.再筛选出大于1的突出
  res=models.Book.objects.annotate(author_num=Count('author')).filter(author_num__gt=1).values('title','author_num')
    # < QuerySet[{'title': '西游记', 'author_num': 3}] >
    print(res)

    #4.查询出各个作者出的书的总价格
  res=models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
    #<QuerySet [{'name': 'json', 'sum_price': Decimal('555.00')}, {'name': 'tank', 'sum_price': Decimal('555.00')}, {'name': 'Nick', 'sum_price': Decimal('555.00')}]>
    print(res)

F与Q查询

 '''F与Q查询'''
    from django.db.models import F,Q
    '''F:表字段的值'''
    #1.查询库存数大于卖出数的书籍
    res=models.Book.objects.filter(kun_cun__gt=F('mai_chu'))#后面跟的是数据库表中字段值
    print(res)#<QuerySet [<Book: 西游记>, <Book: 水浒传>]>

    #2.将所有书的价格上涨100
    models.Book.objects.all().update(price=F('price')+100)

    # 3.将所有书的名称后面全部加上 "爆款" 后缀    了解知识点    操作字符串数据需要借助于Concat方法
    from django.db.models.functions import Concat
    from django.db.models import Value
    ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))

    '''Q:将and条件改成or'''
    #1.查询一下书籍名称是三国演义或者库存数是500的书籍
    res=models.Book.objects.filter(title='三国演义',kun_cun=500) #and关系
    res=models.Book.objects.filter(Q(title='三国演义'),Q(kun_cun=500))# Q包裹之后还是and关系
    res=models.Book.objects.filter(Q(title='三国演义')|Q(kun_cun=500))# |就是or的关系
    res=models.Book.objects.filter(~Q(title='三国演义')|Q(kun_cun=500))# ~就是not的关系
    print(res)

    # @对象高级用法
    #按字符串查询
    q=Q()
    q.connector='or' #默认是and,可以改成or
    q.children.append(('title','三国演义'))
    q.children.append(('kun_cun__gt',500))
    res=models.Book.objects.filter(q)
    res=models.Book.objects.filter(~q) #取反
    print(res)

orm字段及参数

1.CharField: mysql中的varchar

2.IntegerField: mysql中的int

3.BigIntegerField: mysql中的bigint

4.EmailField: mysql中的varchar(254)

5.DateField:
DateTimeField:
auto_now:每次修改数据的时候,都会自动将当前修改时间更新上去
auto_now_add:在创建数据的时候,会将当前时间自动记录,之后就不会自动修改时间了,除非认为手动的修改

6.AutoField: mysql中的auto_increment

7.BooleanField: mysql中的布尔值
该字段在存储的时候,只需要传入True或者False。会自动存成1/0

8.TextField: 专门用来存大段文本的

9.FileField:专门用来存放文件路径
upload_to='/etc/data'
给该字段传值的时候,直接传文件对象,会自动将文件对象保存在upload_to后面指定的文件路径中。然后将路径保存到数据库中

10.DecimalField(Field): 10进制小数
参数:max_digits:小数总长度 decimal_places:小数位长度

自定义char字段

#如何自定义字段类型
class MyCharField(models.Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length=max_length
        #重新调用父类的方法
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self,connection):
        return 'char(%s)'%self.max_length

orm中的事务操作

什么是事务:
将多个sql语句操作变成原子性操作,要么同时成功,有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对于事务则是部分支持)

四大特性ACID:
原子性
一致性
隔离性
持久性

django如何开启事务:

from django.db import transaction
with transation.atomic():
    #在缩进的代码中书写数据库操作,该缩进内的所有代码都是一个事务

数据库设计三大范式:
当一个关系表中的所有分组都是不可再分的数据项时,该关系表是规范的
第一范式条件:必须不包含重复组的关系,即每一列都是不可拆分的原子项
第二范式条件:关系模式必须满足第一范式,并且所有非主属性完全依赖于主码(就是说非主属性字段必须和主属性字段有关系)
第三范式条件:在满足第二范式后,所有非主属性字段跟主属性有直接关系而不是间接的或者传递的关系

图书管理系统

orm相关的数据库查询优化

posted @ 2019-11-28 23:32  风啊风啊  阅读(145)  评论(0编辑  收藏  举报