django orm(2)
聚合函数
这里的聚合函数和SQL里的聚合函数对应,在使用前需要先进行模块的导入:
from django.db.models import Max,Min,Sum,Count,Avg
常用的聚合函数有求最大值、最小值、和、计数、平均数,具体使用看下面几个例子:
筛选出价格最高的书籍
res = models.Book.objects.aggregate(mr = Max('price'))
求书籍的总价格
res1 = models.Book.objects.aggregate(mr = Sum('price'))
求书籍的平均价格
res1 = models.Book.objects.aggregate(agv1 = Agv('price'))
求书籍的最大值、最小值、平均价格、总价格
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)的更多相关文章
- django orm总结[转载]
django orm总结[转载] 转载地址: http://www.cnblogs.com/linjiqin/archive/2014/07/01/3817954.html 目录1.1.1 生成查询1 ...
- Django ORM - 001 - 外键表查询主表信息
开始用Django做web开发,我想大家都会遇到同样的问题,那就是如何高效快速的查询需要的数据,MVC都很简单,但是ORM折腾起来就有些费时间,我准备好好研究下Django ORM,所以会有一个系列的 ...
- Django ORM 中的批量操作
Django ORM 中的批量操作 在Hibenate中,通过批量提交SQL操作,部分地实现了数据库的批量操作.但在Django的ORM中的批量操作却要完美得多,真是一个惊喜. 数据模型定义 首先,定 ...
- Django ORM 查询管理器
Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...
- Django ORM模型的一点体会
作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载. 使用Python的Django模型的话,一般都会用它自带的ORM(Object-relational ma ...
- 数据库表反向生成(二) Django ORM inspectdb
在前一篇我们说了,mybatis-generator反向生成代码. 这里我们开始说如何在django中反向生成mysql model代码. 我们在展示django ORM反向生成之前,我们先说一下怎么 ...
- Django ORM那些相关操作
一般操作 https://docs.djangoproject.com/en/1.11/ref/models/querysets/ 官网文档 常用的操作 <1> all() ...
- django orm 及常用参数
一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...
- Django ORM中,如何使用Count来关联对象的子集数量
示例models 解决方法 有时候,我们想要获取一个对象关联关系的数量,但是我们不要所有的关联对象,我们只想要符合规则的那些关联对象的数量. 示例models # models.py from dja ...
- Django ORM存储datetime 时间误差8小时问题
今天使用django ORM 将获取到的时间入库,并未出现问题,但是后来发现时间晚了8小时,经查询Django官方文档发现获取本地时间和UTC时间有差别. 首先科普下:UTC是协调世界时 UTC相当于 ...
随机推荐
- Vue的父子组件通信(转载)
Vue是一个轻量级的渐进式框架,对于它的一些特性和优点在此就不做赘述,本篇文章主要来探讨一下Vue子父组件通信的问题 首先我们先搭好开发环境,我们首先得装好git和npm这两个工具(如果有不清楚的同学 ...
- spring的组件工厂后置处理器——BeanFactoryPostProcessor
作用和调用时机 spring有两种后置处理器: 1. 组件后置处理器——org.springframework.beans.factory.config.BeanPostProcessor: 2. 工 ...
- Selenium学习之==>WebDriverApi接口详解
浏览器操作 driver.back() # 后退 driver.forward() # 前进 driver.refresh() # 刷新 窗口操作 driver.get_window_size() # ...
- node.js ffmpeg-concat 命令行形式处理多个视频的过度效果
ffmpeg-concat 是利用 gl-transitions 处理多个视频的过度效果.详细说明参见 https://github.com/transitive-bullshit/ffmpeg-co ...
- java通过jna调用so
c++: FirstEliteValidate.h #pragma once void __attribute__((constructor)) startup();void __attribute_ ...
- PHP 数组函数 内部指针
current( &$arr ) 每个数组的当前单元,初始值的 数组的第一个单元next ( &$arr ) 返回数组中的下一个单元 , 如果没值则返回falshprev ( & ...
- java基础/java调用shell命令和脚本
一.项目需求: 从某一机构获取证书,证书机构提供小工具,执行.sh脚本即可启动服务,本地调用该服务即可获取证书. 问题:linux服务器启动该服务,不能关闭.一旦关闭,服务即停止. 解决方案:java ...
- vscode打开SpringBoot项目
1.使用vscode打开java项目所在文件夹 2.按ctl+~ 打开命令面板 mvn -Dmaven.test.skip=true spring-boot:run
- [DS+Algo] 010 二叉树的遍历
二叉树遍历 深度优先 一般用递归 一些名词 遍历方式 英文 先序 Preorder 中序 Inorder 后序 Postorder 广度优先 一般用队列 Python 代码示例 class Node( ...
- oracle_fdw安装及使用(无法访问oracle存储过程等对象)
通过oracle_fdw可以访问oracle中的一些表和视图,也可以进行修改,尤其是给比较复杂的系统使用非常方便. (但不能使用oracle_fdw来访问oracle的存储过程.包.函数.序列等对象) ...