聚合函数

这里的聚合函数和SQL里的聚合函数对应,在使用前需要先进行模块的导入:

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

常用的聚合函数有求最大值、最小值、和、计数、平均数,具体使用看下面几个例子:

  1. 筛选出价格最高的书籍

    res = models.Book.objects.aggregate(mr = Max('price'))
  2. 求书籍的总价格

    res1 = models.Book.objects.aggregate(mr = Sum('price'))
  3. 求书籍的平均价格

    res1 = models.Book.objects.aggregate(agv1 = Agv('price'))
  4. 求书籍的最大值、最小值、平均价格、总价格

    res1 = models.Book.objects.aggregate(mp = Max('price'), mi = Min('price'),cou = Count('price'),sum1 = Sum('price'),avg1 = Avg('price'))
    
    print(res1)
    #{'mp': Decimal('100.00'), 'mi': Decimal('10.00'), 'cou': 6, 'sum1': Decimal('312.00'), 'avg1': 52.0}

分组查询

分组查询主要应用在比如查询班级中男生、女生的个数等需要先分组再查询的场景,分组操作使用的annotate内部调用的是SQL语句group by,分着查询需要和聚合函数联用。按谁分组,models就是谁,annotaten内部传入筛选的条件。

通过下面几个例子看Django的分组查询:

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

这里就需要每一本书为一组,然后统计每本书的作者的个数:

res = models.Book.objects.annotate(author_num=Count('author__id')).values('name','author_num')
print(res)
#<QuerySet [{'name': '乖,摸摸头', 'author_num': 2}, {'name': '向着光亮那方', 'author_num': 1}, {'name': '你坏', 'author_num': 1}, {'name': '你的孤独虽败犹荣', 'author_num': 1}, {'name': '三体', 'author_num': 0}, {'name': '乡村教师', 'author_num': 0}]>

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

res = models.Publisher.objects.annotate(min_price=Min('book__price')).values('publisher_name','book__name','book__price')
print(res)
#<QuerySet [{'publisher_name': '湖南文艺出版社', 'book__name': '你坏', 'book__price': Decimal('49.00')}, {'publisher_name': '大象出版社', 'book__name': '乖,摸摸头', 'book__price': Decimal('50.00')}, {'publisher_name': '人民文学出版社', 'book__name': '向着光亮那方', 'book__price': Decimal('51.00')}]>

按照某一个字段进行分组,然后按照另一字段进行查找或排序。

# res = models.Publish.objects.values('想要分组的字段名').annotate(min_price=Min('book__price')).values('name','min_price')

res = models.Book.objects.values('price').annotate(min_price=Min('price')).values('name','min_price')
print(res)
#<QuerySet [{'name': '乖,摸摸头', 'min_price': Decimal('50.00')}, {'name': '向着光亮那方', 'min_price': Decimal('51.00')}, {'name': '你坏', 'min_price': Decimal('49.00')}, {'name': '你的孤独虽败犹荣', 'min_price': Decimal('52.00')}, {'name': '三体', 'min_price': Decimal('100.00')}, {'name': '乡村教师', 'min_price': Decimal('10.00')}]>

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

res = models.Book.objects.annotate(author_num=Count('author__id')).filter(author_num__gt=1).values('name','author_num')
print(res)
#<QuerySet [{'name': '乖,摸摸头', 'author_num': 2}]>

4.查询各个作者出的书的总价格,打印作者名字,总价格

关键字:annotate

借助于聚合函数,Django中models后面点什么就按什么分组

res2 = models.Author.objects.annotate(sum_price=Sum('book__price')).values('auth_name','sum_price')
# print(res2)
#<QuerySet [{'auth_name': '刘同', 'sum_price': Decimal('153.00')}, {'auth_name': '大冰', 'sum_price': Decimal('99.00')}, {'auth_name': '刘慈欣', 'sum_price': None}]>

F与Q查询

使用F和Q查询前需要先导入模块:

from django.db.models import F,Q

F查询

F查询主要解决字段与字段间对比查询的问题,双下划线查询只能实现单个字段的范围查询,引入F查询我们就能够实现不同字段间的对比查询,比如查询出库存数大于卖出数的书籍就是库存和卖出两个字段的对比查询。这里的字段需要在同一张表内方可。

# 1. 查询库存数大于卖出数的书籍
res3 = models.Book.objects.filter(stock__gt=F('sell')).values('name')
print(res3)
#<QuerySet [{'auth_name': '刘同', 'sum_price': Decimal('153.00')}, {'auth_name': '大冰', 'sum_price': Decimal('99.00')}, {'auth_name': '刘慈欣', 'sum_price': None}]><QuerySet []> # 2. 将所有书的价格上涨100块
book_objs = models.Book.objects.all().update(price=F('price')+100)
print(book_objs.values('price')) # 3.将所有书的名称后面全部加上 "爆款" 后缀,操作字符串数据需要借助于Concat方法
from django.db.models.functions import Concat
from django.db.models import Value
res4 = models.Book.objects.update(name=Concat(F('name'),Value('新作')))

Q查询

利用Q查询可以实现filter()查询时,查询条件的或非(| 、~)的关系。

说明:如果Q对象和关键字参数一起使用,Q对象必须放在前面。

# 1.查询一下书籍名称是乡村教师 或者 库存数是500的书籍
res4 = models.Book.objects.filter(Q(name='乡村教师新作')|Q(stock=500)).values('name')
print(res4)#或
#<QuerySet [{'name': '三体新作'}, {'name': '乡村教师新作'}]>
#查询出除乡村教师新版和库存数等于500的书籍名称
res5 = models.Book.objects.filter(~Q(name='乡村教师新作')|~Q(stock=500)).values('name')
print(res5)#非

Q对象的高级用法

我们可以根据要求不断给q对象添加筛选条件,然后进行查询,如:

# 1.查询一下书籍名称是乡村教师 或者 库存数是500的书籍
q = Q()#实例化一个Q的对象,之后我们可以按照我们的要求给q添加条件
q.connector = 'or'#默认是and,这里设置的就是各筛选条件之间的关系
q.children.append(('name','乡村教师新作'))#添加筛选条件name='乡村教师'
q.children.append(('stock',500))#添加筛选条件stock=500
res6 = models.Book.objects.filter(q).values('name')#按照我们的要求进行筛选
print(res6)

事务

事务的操作相当于起了一个单独的进程,当操作执行成功之前,数据库中的数据不会有任何的变化,只有当操作结束且执行成功了数据库中的数据才会发生变化,而且这个变化是不可逆的,在操作未执行结束时(没有提交数据时)可以如果我们的操作有错误,可以执行回滚指令,撤销前面的操作(这里的撤销是撤销前面的所有),事务的原子性其实就是我们起一个事务对多张表进行数据操作时,要么这多张表同时被修改成功,要么都不被修改。银行转账就是利用了事务的这一特点。

Django中的事务

还未进行详细讲解

orm字段及参数

常用字段:

字段 描述
AutoField int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField 一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)
CharField varchar类型,必须提供max_length参数, max_length表示字符长度。
DateField 日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

字段参数:

参数 描述
null 用于表示某个字段可以为空。
unique 如果设置为unique=True 则该字段在此表中必须是唯一的 。
db_index 如果db_index=True 则代表着为此字段设置索引。
default 为该字段设置默认值。
auto_now_add (日期与时间字段参数)配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
auto_now (日期与时间字段参数)配置上auto_now=True,每次更新数据记录的时候会更新该字段。

Django字段集合

    AutoField(Field)
- int自增列,必须填入参数 primary_key=True BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True 注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32) class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647 BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field)
- 布尔值类型 NullBooleanField(Field):
- 可以为空的布尔值 CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度 TextField(Field)
- 文本类型 EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both" URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号) CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字 UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹 FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field)
- 浮点型 DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度 BinaryField(Field)
- 二进制类型 字段合集

Django的字段与数据库字段的对应关系:

对应关系:
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)', ORM字段与MySQL字段对应关系

自定义char字段

自定义字段可以使用下面的方法,其实我们也只是更改一下字段的数据长度、字段的名字等,Django中的字段已经很丰富了。

# 如何自定义字段类型
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

django orm(2)的更多相关文章

  1. django orm总结[转载]

    django orm总结[转载] 转载地址: http://www.cnblogs.com/linjiqin/archive/2014/07/01/3817954.html 目录1.1.1 生成查询1 ...

  2. Django ORM - 001 - 外键表查询主表信息

    开始用Django做web开发,我想大家都会遇到同样的问题,那就是如何高效快速的查询需要的数据,MVC都很简单,但是ORM折腾起来就有些费时间,我准备好好研究下Django ORM,所以会有一个系列的 ...

  3. Django ORM 中的批量操作

    Django ORM 中的批量操作 在Hibenate中,通过批量提交SQL操作,部分地实现了数据库的批量操作.但在Django的ORM中的批量操作却要完美得多,真是一个惊喜. 数据模型定义 首先,定 ...

  4. Django ORM 查询管理器

    Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...

  5. Django ORM模型的一点体会

    作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载. 使用Python的Django模型的话,一般都会用它自带的ORM(Object-relational ma ...

  6. 数据库表反向生成(二) Django ORM inspectdb

    在前一篇我们说了,mybatis-generator反向生成代码. 这里我们开始说如何在django中反向生成mysql model代码. 我们在展示django ORM反向生成之前,我们先说一下怎么 ...

  7. Django ORM那些相关操作

    一般操作 https://docs.djangoproject.com/en/1.11/ref/models/querysets/         官网文档 常用的操作 <1> all() ...

  8. django orm 及常用参数

    一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...

  9. Django ORM中,如何使用Count来关联对象的子集数量

    示例models 解决方法 有时候,我们想要获取一个对象关联关系的数量,但是我们不要所有的关联对象,我们只想要符合规则的那些关联对象的数量. 示例models # models.py from dja ...

  10. Django ORM存储datetime 时间误差8小时问题

    今天使用django ORM 将获取到的时间入库,并未出现问题,但是后来发现时间晚了8小时,经查询Django官方文档发现获取本地时间和UTC时间有差别. 首先科普下:UTC是协调世界时 UTC相当于 ...

随机推荐

  1. 【nginx】常用命令 启动|停止|重启|重新读取配置-centOS7

     查看服务的当前状态 (flaskApi) [root@67 goTest]# systemctl status nginx.service ● nginx.service - The nginx H ...

  2. 通过 vSphere WS API 获取 vCenter Datastore Provisioned Space 置备空间

    目录 文章目录 目录 Provisioned Space & Used Space Provisioned Space 的计算方式 Uncommitted Space 扩展:置备率的计算公式 ...

  3. fiddler之入门(安装配置)

    在工作中常常需要进行数据的抓包和发包,此时就可以用到fiddler这个工具了. fiddler是一个http协议调试代理工具,通过http代理,让数据从其通过,来坚挺本地计算机与访问网络之间的所有ht ...

  4. Linux(Ubuntu)常用命令 & vim基本操作

    Linux先知: Linux历史: 关于这个我就不再多说了,其实是一个很有意思的故事串,网上找下一大堆. 类Unix系统目录结构: ubuntu没有盘符这个概念,只有一个根目录/,所有文件都在它下面 ...

  5. 【BASIS系列】SAP Basis系统管理中重置用户缓冲哪些需要注意

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BASIS系列]SAP Basis系统管理中重 ...

  6. 获取kafka最新offset-scala

    无论是在spark streaming消费kafka,或是监控kafka的数据时,我们经常会需要知道offset最新情况 kafka数据的topic基于分区,并且通过每个partition的主分区可以 ...

  7. 洛谷 P5662 纪念品 & [NOIP2019普及组] (dp,完全背包)

    传送门 解题思路 本题首先要明白,在每一天时,最优策略是先进行操作2(卖),再进行操作1(买),才能是利益最大化. 本题很显然当只有两天时,是一个完全背包,就是把当日价钱当做体积,把明日价格和今日价格 ...

  8. nginx重新编译安装upload模块

    由于php处理上传会出现超时,并且显示上传进度官方php不支持nginx+php,所以决定让nginx自己处理上传,我本地环境是mac上已经安装过nginx1.8.0,安装方式为brew,所以需要重新 ...

  9. 如何配置vsftpd服务器

    1,通过yum查看本地是否存在vsftpd rpm -qa|grep vsftpd [root@node2 ~]# rpm -qa |grep vsftpdvsftpd-3.0.2-25.el7.x8 ...

  10. python递归方式和普通方式实现输出和查询斐波那契数列

    ●斐波那契数列 斐波那契数列(Fibonacci sequence),是从1,1开始,后面每一项等于前面两项之和. 如果为了方便可以用递归实现,要是为了性能更好就用循环. ◆递归方式实现生成前30个斐 ...