django6-orm进阶操作
1.创建django环境的脚本
在自定义脚本中操作orm ,但是自定义脚本中不具备django的环境
- ###test.py 脚本,引入django的环境即可使用orm操作数据库
import os- if __name__ == "__main__":
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django1.settings")
- import django
- django.setup()
- from app1 import models
2.orm字段的类型
AutoField 自增长字段 ,代替默认的id字段成为表的主键 ,必须有主键参数
BooleanField 布尔值字段 ,可以是0或1
CharField 字符串类型 ,默认使用边长的varchar类型
IntegerField 整数类型 ,最好用charfield存
DecimalField 小数类型 ,可以限定整体的最大长度max_digits ,限定小数位长度decimal_places(四舍五入)
DateTiemField 日期时间类型 ,常用两个参数 标记时间节点 auto_now_add自动记录创建时间 ,auto_now自动记录修改时间
- test_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=32)
- sex = models.BooleanField()
- age = models.IntegerField()
- price = models.DecimalField(max_digits=10, decimal_places=2)
- create_time = models.DateField(auto_now_add=True)
- update_time = models.DateField(auto_now=True)
3.orm字段的参数
null = True 该字段是否可以为空 ,True表示可以为空
default= '默认值' 该字段为空时的默认值
primary_key=True 指定该字段为主键
db_index 为字段创建索引
db_column= '属性名' 默认django的字段名与db中的名字是一致的 ,db_column可以改变db中该字段的名字
4.自定义字段
根据数据库中的字段类型, 自定义django的orm的字段 ,比如ChairField默认使用的是varchar速度较慢 ,我们换成定长的char类型
- class MycharField(models.Field):
- """
- 自定义的char类型的字段类
- """
- def __init__(self, max_length, *args, **kwargs):
- self.max_length = max_length
- super(MycharField, self).__init__(max_length=max_length, *args, **kwargs)
- def db_type(self, connection):
- """
- 指定字段数据库类型
- :param connection:
- :return:
- """
- return 'char({})'.format(self.max_length)
- class testn(models.Model):
- name = MycharField(max_length=12)
5.django的admin后台管理系统
使用web操作界面操作我们的orm对象 ,完成对数据库的修改 ,其中可以将我们想通过界面操作的表都注册
- ###创建管理员###
- python manage.py createsuperuser
- ###settings.py设置一下中文 LANGUAGE_CODE = 'zh-hans'
- ###注册到admin中### from django.contrib import admin from app1 import models
- # 将表注册在admin系统
- admin.site.register(models.presslist)
- admin.site.register(models.Book)
字段参数与admin系统相关的
blank = False #该字段再admin界面填写不能为空
BooleanField(choices=((0,'男'),(1,'女'))) #布尔值类型与admin界面显示建立对应关系
嵌套类与admin系统关系类Meta
- class Person1(models.Model):
- ......
- ......
- def __str__(self):
- return 'obj:{}'.format(self.name)
- class Meta:
- db_table = "Person" ##数据库的表默认是与类名一致 ,这里可以自定义
- # 定义admin后台管理系统中该表每条数据的名字
- verbose_name = '个人信息'
- # 定义admin后台管理系统中整张表的意义名字
- verbose_name_plural = '所有用户信息'
6.常规操作(查询筛选排序)
分类:通过返回结果分类
返回QuerySet的:all filter exclude values values_list distinct order_by reverse
返回对象的: get first last
返回布尔值: exists
返回数字的: count
详细使用:
models.类名.object.create(属性=值,属性=值...) #创建一条记录
models.类名.object.all() #取出所有对象放入对象列表
models.类名.object.get('字段'=值) #获取对象,有重复值或者不存在都会报错 ,仅取唯一对象
models.类名.object.filter('字段'=值) #可以获取匹配所有对象 ,放入对象列表
models.类名.object.filter('字段'=值).exists() #可以获取匹配所有对象 ,匹配直接返回bool值
models.类名.object.exclude('字段'=值) #与filter作用相反
models.类名.object.filter('字段' = 值).fist() #取出对象列表的第一个对象
models.类名.object.filter('字段' = 值).last() #取出对象列表的第最后一个对象
models.类名.object.all().values() #取出对象列表中所有对象的属性以字典形式放入列表
models.类名.object.all().values().distinct() #取出对象列表中所有对象的属性以字典形式放入列表 ,去重!!!!
models.类名.object.all().values_list() #取出对象列表中所有对象的属性以字典形式放入元组
models.类名.object.all().values_list('字段1','字段2') #仅显示某些字段
models.Person1.objects.order_by('age') #按照age属性,升序排序放入对象列表
models.Person1.objects.order_by('-age') #按照age属性,降序排序放入对象列表
models.Person1.objects.order_by('-age','pk') #先按照age属性降序排列,当age一样,再按照nid属性进行升序排列放入对象列表
models.Person1.objects.order_by('-age', 'pk') #对象列表数据翻转!!!
技巧: 先取出对象列表 ,对对象列表灵活操作
7.双下划线查询(模糊匹配,范围筛选)
场景: 获取cpu是16和8的所有对象 ,获取主键小于100的所有对象 ,找到字段1为空的所有对象
1)对属性范围划分
gt大于 lt小于 gte大于等于 lte小于等于 in在元祖内的匹配 range范围匹配
print(models.HostInfo.objects.filter(Cpu__lt=8))
print(models.HostInfo.objects.filter(Cpu__gte=8))
print(models.HostInfo.objects.filter(Cpu__in=(2,4)))
print(models.HostInfo.objects.filter(Cpu__range=(8,64)))
2)对属性模糊匹配
模糊匹配: contains='匹配关键字' #只要该字段包含关键字就会被列出 icontains不区分大小写
print(models.HostInfo.objects.filter(IP__contains='1.1.1'))
开头结尾匹配: startswith endswith istartswith iendswith #匹配开头到开头结尾对象就会被列出 ,加 'i' 不区分大小写
print(models.HostInfo.objects.filter(IP__contains='1.1.1'))
3)匹配空字段与否
可以将某个字段为空或不为空的全部列出来
print(models.HostInfo.objects.filter(hostname__isnull=False)
print(models.HostInfo.objects.filter(hostname__isnull=True)) #列出hostname字段为空的所有对象
8.orm外键跨表查询 ,外键一对多
这里我将 多的一方称为多表 , 一的一方称为一表
多表中存在一表的id值 ,作为外键的关联字段 ,查询分为查询方向(正向,反向)查询结果(对象 ,属性)
- ####外键两张表 一对多 多对多三张表
##models.py
class presslist(models.Model):- name = models.CharField(max_length=32)
- def __str__(self):
- return self.name
- class Book(models.Model):
- name = models.CharField(max_length=32)
- p_id = models.ForeignKey('presslist', on_delete=models.CASCADE)
- def __str__(self):
- return self.name
- class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField('Book')- def __str__(self):
return self.name
- ###########注册到admin中
##造数据
- # models.presslist.objects.create(name='樱花出版社')
# models.presslist.objects.create(name='葡萄出版社')
# models.presslist.objects.create(name='农夫出版社')
# models.presslist.objects.create(name='苹果出版社')
# models.presslist.objects.create(name='桃子出版社')- # models.Book.objects.create(name='python初级',p_id_id=11)
# models.Book.objects.create(name='python中级',p_id_id=13)
# models.Book.objects.create(name='python高级',p_id_id=14)
# models.Book.objects.create(name='java初级',p_id_id=15)
# models.Book.objects.create(name='java高级',p_id_id=11)- # models.Book.objects.create(name='service mesh',p_id_id=12)
- # models.Book.objects.create(name='django框架',p_id_id=12)
外键之正向查询 : 使用多表对象获取一表的对象或者属性(多表有外键字段)
- # 跨表获取一表对象! 跨表获取一表属性
- obj = models.Book.objects.filter(name='python初级').first()
- print(obj.p_id) #一表对象
- obj1 = models.Book.objects.values_list("p_id__pk") #一表属性
- print(obj1)
外键之反向查询 : 使用一表对象获取多表的对象或属性(一表无外键字段 ,但是有关系管理对象_set)
- # 跨表获取多表对象 ! 跨表获取一表属性
obj2 = models.presslist.objects.filter(name='樱花出版社').first()- print(obj2.book_set.all()) #多表对象
- obj3 = models.presslist.objects.values_list('book__name') #多表属性
- print(obj3)
外键跨表查询看似混乱 ,实际很简单 ,多表使用字段 ,一表使用关系管理对象_set 。多使用value
9.多对多跨查询
多对多则没有正反查询, 其中拥有ManyToManyField字段的表可以通过, 属性.all()获取关系管理对象 . 没有ManyToManyField字段的表通过 另张表名_set.all()获取关系管理对象
- obj = models.Author.objects.filter(name='鲁迅')[0]
print(obj.books.all().values()) #跨表查询作者为鲁迅的所有书籍对象- obj1 = models.Book.objects.filter(name='python初级')[0]
- print(obj1.author_set.all().values()) #跨表查询书籍为'python初级'的所有作者对象
10.外键与多对多的新增 ,关联 ,删除
1)跨表创建记录 ,根据一个表的对象, 创建另一张表记录
- # 给作者对象跨表加本书
- auth = models.Author.objects.filter(name='鲁迅')[0]
- auth.books.create(name='故事会', p_id_id=12)
- print(auth.books.all().values())
- # 给书对象跨表加个作者
- bk = models.Book.objects.filter(name='java初级')[0]
- bk.author_set.create(name='苏轼')
- print(bk.author_set.all().values())
2)跨表关联已有对象
- #给已有的书关联一个已有作者
- bk = models.Book.objects.filter(name='java初级')[0]
- bk.author_set.add(*[1])
- print(bk.author_set.all().values())
- #给已有的作者关联一个已有的书
- auth = models.Author.objects.filter(name='佚名')[0]
- auth.books.add(*[14,15,16])
- print(auth.books.all().values())
3)跨表删除
remove() #删除指定关系
clear() #清空关系
set() #清空+重置关系
- #给已有的书删除一个已有作者
- bk = models.Book.objects.filter(name='java初级')[0]
- bk.author_set.remove(*[1])
- print(bk.author_set.all().values())
- #给已有的作者删除一个已有的书
- auth = models.Author.objects.filter(name='佚名')[0]
- auth.books.remove(*[14,15,16])
- print(auth.books.all().values())
11.高级查询
1)聚合查询
相当于mysql中的聚合函数(avg ,sum ,count ,max...) ,貌似仅用于int类型
需要加载聚合函数 ,使用aggregate()方法 ,可以同时执行多个聚合函数查询 ,返回字典
- ##
- from django.db.models import Avg, Sum, Count, Max, Min
- print(models.Book.objects.aggregate(Sum('pk'), Max('pk'), Min('pk'), Avg('pk'), Count('pk')))
2)分组查询
根据一个条件分组 ,如对书进行分组 ,可以使用本表的p_id出版社分组 ,也可以使用跨表的作者条件分组
先获取对象列表 ,再使用annotate
- ##加入一个字段book表
- price = models.IntegerField(max_length=32)
- print(models.Book.objects.values('author__name').annotate(sum=Sum('price'))) #将书以作者名字分组
print(models.Book.objects.values('p_id_id').annotate(sum=Sum('price')).values('p_id__name','sum')) #将书以出版社名字分组
3)F查询 ,F更新
F能拿出其他字段数据作为条件!!!!!!!!
F是个神奇的东西 ,可以理解为能把其他字段的值拿过来使用 ,如我有两个字段 销量 库存 ,F操作更新库存update=销量*2 ,F操作查询库存<销量
F查询为book新增销量与库存字段! !数据迁移 ,手动添加数据
- xl = models.IntegerField(max_length=32)
- kc = models.IntegerField(max_length=32)
F查询 :销量大于库存的书 ,销量小于库存的书
- from django.db.models import F
- print(models.Book.objects.filter(xl__lt=F('kc')).values('xl','kc'))
- print(models.Book.objects.filter(xl__gt=F('kc')).values('xl','kc'))
F更新 :保证库存为销量的3倍值
- models.Book.objects.update(kc=F('xl') * 3)
- print(models.Book.objects.all().values('xl', 'kc'))
4)Q逻辑关系筛选
Q和F没有关系 - - ,Q可以做逻辑筛选 & | ~ (与或非)
Q筛选 :不超过100元的书且属于樱花出版社的书有哪些
- from django.db.models import Q
- print(models.Book.objects.filter(Q(price__lt=100) & Q(p_id_id=11)).values('price','p_id__name'))
Q筛选 :价格在100以上和50以下的书籍
- print(models.Book.objects.filter(Q(price__gt=100) | Q(price__lt=50)).values('price'))
12.事务
一些列sql操作组成一个整体 ,当所有sql成功 ,那么整体就是成功的. 如果其中一条sql失败了那么全部回滚
使用transaction(交易)模块的atomic(原子)方法 ,但是外层需要异常处理 ,肯定会中断程序
with transaction.atomic():
sql
sql
- from app1 import models
- from django.db import transaction
- try:
- with transaction.atomic():
- models.Book.objects.create(name='mysql事务1', p_id_id=12, price=67, xl=0, kc=20)
- models.Book.objects.create(name='mysql事务进阶1', p_id_id=13, price=87, xl=0, kc=20)
- int('ol')
- except Exception as e:
- print(e)
django6-orm进阶操作的更多相关文章
- Django中的ORM进阶操作
Django中的ORM进阶操作 Django中是通过ORM来操作数据库的,通过ORM可以很easy的实现与数据库的交互.但是仍然有几种操作是非常绕也特别容易混淆的.于是,针对这一块,来一个分类总结吧. ...
- ORM 进阶操作
ORM多表操作 一.创建模型 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息:作者详情模型和作者模型之间是一对一的关系. 出版商模型:出版商有 ...
- ORM进阶操作
一.聚合查询:aggregate(*args, **kwargs) aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典.键的名称是聚合值的标识符,值是计 ...
- web框架-(七)Django补充---models进阶操作及modelform操作
通过之前的课程我们可以对于Django的models进行简单的操作,今天了解下进阶操作和modelform: 1. Models进阶操作 1.1 字段操作 AutoField(Field) - int ...
- Django orm进阶查询(聚合、分组、F查询、Q查询)、常见字段、查询优化及事务操作
Django orm进阶查询(聚合.分组.F查询.Q查询).常见字段.查询优化及事务操作 聚合查询 记住用到关键字aggregate然后还有几个常用的聚合函数就好了 from django.db.mo ...
- django 2 ORM操作 ORM进阶 cookie和session 中间件
ORM操作 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...
- Django之Models进阶操作(字段属性)
字段属性详细介绍 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列, ...
- ORM进阶之Hibernate 的三大对象
ORM进阶之 ORM简单介绍 ORM进阶之Hibernate 简单介绍及框架搭 ORM进阶之Hibernate 的三大对象 我们在上一篇博客中讲到了怎样搭建一个Hibernate框架, 提到Hiber ...
- Django 之models进阶操作
到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 ...
- Django ORM models操作
title: Django ORM models操作 tags: Django --- Django ORM models操作 Django ORM基本操作 一.数据库的创建及增删改查 1 使用类创建 ...
随机推荐
- React 从入门到进阶之路(二)
在之前的文章中我们介绍了 React 开发的环境搭建及目录介绍和整理,本篇文章将介绍 React 创建组件.JSX 语法.绑定数据和绑定对象. 之前我们已经将项目运行了起来,我们再来看一下目录结构: ...
- NIO中Buffer的重要属性关系解析
Buffer 是java NIO中三个核心概念之一 缓存, 在java的实现体系中Buffer作为顶级抽象类存在 简单说,Buffer在做什么? 我们知道,在java IO中体系中, 因为InputS ...
- 前端深入之js篇丨Array数组操作从入门到成神Up Up Up,持续更新中
写在前面 随着前端深入的不断学习,发现数组这个数据结构在前端中有着相当大的存在感,由于我初学前端的时候并没有系统性的学习数组,所以我将通过这篇文章同你一起学习数组,希望我们能一起进步,学会熟练操作数组 ...
- [Spring cloud 一步步实现广告系统] 9. 主类和配置文件
搜索系统启动主类 /** * AdSearchApplication for 广告搜索服务启动类 * * @author <a href="mailto:magicianisaac@g ...
- 清新三角格子风工作报告季度总结年终汇报通用PPT模板
选好合适的PPT模板,确定好主题,一个漂亮的PPT首先要简洁,其次文字不要太多,能用图片或视频讲解的最好用图片或视频.做好ppt后,对于讲解演示,也要提前做好练习准备. 模版来源:http://ppt ...
- Masonry纯码实现UIScrollView 之上下滚动,设置UIScrollView背景图片
参考链接:https://www.jianshu.com/p/9a158308c50b 亲测有效,很赞! 你们最想要的Demo下载地址:https://github.com/objcxiaobai/C ...
- Last 2 dimensions of the array must be square
这个报错是因为我们在求解行列式的值的时候使用了: np.linalg.det(D) 但是D必须是方阵才可以进行运算,不是方阵则会报错,我们把之前的行列式更改为方阵就不会再报错了,当然这也是numpy自 ...
- Linux日志中出现大量dhclient mesage浅析
最近检查发现一台Linux服务器,发现其日志里面有大量下面信息,其中部分信息做了脱敏处理.其中一个地址A(192.168.AAA.AAA) 为DNS服务器地址,地址B(192.168.BBB.BBB) ...
- LG1879 「USACO2006NOV」Corn Fields 状压DP
问题描述 LG1879 题解 设\(opt[i][j]\)代表前\(i\)行,且第\(i\)行状态为\(j\)的方案数. 枚举\(j\),再枚举\(k\),\(k\)为上一行的状态. 判断\(j,k\ ...
- LG5196 「USACO2019JAN」Cow Poetry 背包+乘法原理
\(\mathrm{Cow Poetry}\) 问题描述 LG5196 题解 因为每句诗的长度一定是\(k\),所以自然而然想到背包. 设\(opt[i][j]\)代表到第\(i\)位时,结尾为\(j ...