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 使用类创建 ...
随机推荐
- Java每日一面(Part1:计算机网络)[19/10/14]
作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 1.1 说一说TCP的四次挥手 "挥手",即终止TCP连接,断开一个TCP连接池. 需要客户端和服务端总共发出四个包,以 ...
- 简单的PHP上传图片实例
分享一个简单的PHP上传图片实例,本实例主要介绍了上传图片的一些限制判断和上传图片的方法. 首先我们在form表单加上上传附件#file,上传按钮#imgbut,记得给form 表单加上multipa ...
- SpringCloud(五):断路器(Hystrix)和hystrixdashboard图实现链路追踪
第一:关于服务调用和熔断安全: ribbon和Feign: 1. 相当于nigx+doubbe,微服务间的服务调用,API网关的请求转发等内容2. Feign整合了Ribbon和Hystrix Hy ...
- Linux安装docker-compose
下载:curl -L https://get.daocloud.io/docker/compose/releases/download/1.16.1/docker-compose-`uname -s` ...
- FCC---Use the CSS Transform scale Property to Change the Size of an Element
To change the scale of an element, CSS has the transform property, along with its scale() function. ...
- [browser window窗口大小 算是screen补充吧]主要因为移动IE游览器 写了个兼容
先上图吧 来上代码 console.log(window.outerWidth + '--' + window.outerHeight);//只读的整数,声明了整个窗口的XY //IE 不支持此属性, ...
- JS基础语法---String对象
String---->是一个对象 字符串可以看成是字符组成的数组, 但是js中没有字符类型 字符是一个一个的, 在别的语言中字符用一对单引号括起来 在js中字符串可以使用单引号也可以使用双引号 ...
- QT无窗口状态下对键盘事件的监听
Question:最近在搞linux下的一个客户端项目,需要接收键盘事件,但是又不能有界面,这种情况怎么处理呢? int main(int argc, char *argv[]) { QApplica ...
- Java中的“scanf()、cin()、input()"
最近在写一个Java程序时遇到一个问题,就是如何在Java里面输入数值,又叫做获取键盘输入值. 因为c语言里面有scanf(),C++里面有cin(),python里面有input().Java里面有 ...
- tensorflow dataloader 相关内容
Tensorflow dataloader 相关调研:数据读取是训练的开始,是非常关键的一步:下面是调研时搜集到的一些相关链接: 十图详解tensorflow数据读取机制 https://zhuanl ...