聚合函数

这里的聚合函数和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. script标签defer与async的区别

    总结: async 会在文件下载完毕后立即执行 会阻止html parser defer 会下载完以后等html parser结束后执行,保证顺序

  2. 阶段3 1.Mybatis_06.使用Mybatis完成DAO层的开发_5 Mybatis中使用Dao实现类的执行过程分析-查询方法1

    继续运行testFindAll方法.把其他类的断点都删除掉. 只在这里加了断点,所以直接就跳转到这里了.RoutingStatementHandler里面的query方法 继续往下走,断点又回到了这里 ...

  3. Centos 安装 FTP

    安装教程:   基于 CentOS 搭建 FTP 文件服务 搭建完成后,使用windows文件夹访问FTP报错,请确保输入的文件名是否正确,并且您有权访问此文件. 先确认ftp服务正常 修改:   设 ...

  4. 移动端自动化==>AppiumApi接口详解

    Appium 初始化配置信息(Desired Capabilities) Desired Capabilities实际上就是一个字典,它主要用于向Appium Server提供初始化配置参数,如:想要 ...

  5. Python学习之==>集合

    1.简介 集合也是一种数据类型,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复数据的. 2.集合的作用 它可以把一个列表中重复的数据去掉,而不需要你再写判断 可以做关系测试,比 ...

  6. PHP 验证香港身份证ID号

    /**check hk idcard$id = "K548653A";$xx= check_hkid($id);var_dump($xx);**/function check_hk ...

  7. ubutnu同时安装OpenCV2和OpenCV3及contrib

    1.OpenCV2源码安装 安装依赖项 sudo apt-get install build-essential //build-essential是c语言的开发包,包含了gcc make gdb和l ...

  8. Tensorflow Learning1 模型的保存和恢复

    CKPT->pb Demo 解析 tensor name 和 node name 的区别 Pb 的恢复 CKPT->pb tensorflow的模型保存有两种形式: 1. ckpt:可以恢 ...

  9. echars 柱状图 堆叠状态 --》二次封装

    <template> <!-- 柱状图 堆叠 1. 调用页面引入 import EcharsColumnStack from '@/components/echarsColumnSt ...

  10. urllib库认证,代理,cookie

    认证,代理,cookie 1from urllib.request import HTTPBasicAuthHandler, HTTPPasswordMgrWithDefaultRealm, buil ...