ORM执行SQL语句,神奇的双下划线查询,ORM外键字段的创建,外键字段数据的操作,多表查询

一、ORM执行SQL语句

有时候ORM的操作效率较低,我们是可以自己来编写SQL语句的
方式一:
res = models.User.objects.raw('select * from app01_user')
print(list(res))
方式二:
from django.db import connection
cursor = connection.cursor()
cursor.execute('select name from app01_user;')
print(cursor.fetchall())

二、神奇的双下划线查询

1.比较运算符

字段__gt            大于
字段__lt 小于
字段__gte 大于等于
字段__lte 小于等于
1.# 查询年龄大于17的用户数据
res = models.User.objects.filter(age__gt=17)
print(res)
2.# 查询年龄小于17的用户数据
res = models.User.objects.filter(age__lt=17)
print(res)
3.# 查询年龄大于等于17的用户数据
res = models.User.objects.filter(age__gte=17)
print(res)
3.# 查询年龄大于等于17的用户数据
res = models.User.objects.filter(age__lte=17)
print(res)

2.成员运算符

字段__range
# 查询姓名在['jason','xin','kerry']中的用户姓名
res = models.User.objects.filter(name__in=['jason','xin','kerry'])
print(res)

3.范围查询

字段__range
# 查询年龄在18到38范围之内的数据
res = models.User.objects.filter(age__range=(18,58))
print(res)

4.模糊查询

字段__contains                不忽略大小写
字段__icontains 忽略大小写
# 查询名字中含有字母j的数据
res = models.User.objects.filter(name__contains='j')
print(res)

5.日期字段处理

字段__year
字段__month
字段__day

三、ORM外键字段的创建

复习一下mysql外键关系:
一对多:字段建在多的一方
多对多:外键字段统一建在第三张关系表中
一对一:建在任何一方都可以,但是建议建在查询频率较高的表中
1.创建基础表(书籍表、出版社表、作者表、作者详情)
2.确定外键关系
一对多 ORM与MySQL一致 外键字段建在多的一方
多对多 ORM比MySQL有更多变化
1.外键字段可以直接建在某张表中(查询频率较高的)
内部会自动帮你创建第三张关系表
2.自己创建第三张关系表并创建外键字段
详情后续讲解
一对一 ORM与MySQL一致 外键字段建在查询较高的一方

四、ORM的创建

表的创建:
from django.db import models # Create your models here. class Book(models.Model):
"""图书表"""
title = models.CharField(max_length=32,verbose_name='书名')
price = models.DecimalField(max_length=8,decimal_places=2,verbose_name='价格')
publish_time = models.DateTimeField(auto_now_add=True,verbose_name='出版日期') '''django1.x版本外键字段默认都是级联更新删除 django2.x及以上需要自己申明 on_delete=models.XXX '''
# 创建书籍与出版社的一对多外键字段
publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
# 创建书籍与作者的多对多外键字段(多对多字段为虚拟字段 用于告诉ORM自动创建第三张表)
authors = models.ManyToManyField(to='Author') def __str__(self):
return f'出版社对象{self.title}' class Publish(models.Model):
"""出版社表"""
name = models.CharField(max_length=32,verbose_name='名称')
address = models.CharField(max_length=64,verbose_name='地址') def __str__(self):
return f'出版社对象:{self.name}'
class Author(models.Model):
"""作者表"""
name = models.CharField(max_length=32,verbose_name='姓名')
age = models.IntegerField(verbose_name='年龄')
# 创建作者与作者详情表一对一外键字段
author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE) def __str__(self):
return f'作者对象:{self.name}'
class AuthorDetail(models.Model):
"""作者详情表"""
phone = models.BigIntegerField(verbose_name='手机号')
address = models.CharField(max_length=64,verbose_name='家庭住址') def __str__(self):
return f'详情对象:{self.address}'

五、外键字段相关操作

1.一对一

 针对一对多,插入数据可以写表中的实际字段
models.Book.objects.create(title='月亮与六便士',price=999.99,publish_id=1)
models.Book.objects.create(title='小王子',price=999.99,publish_id=1)
models.Book.objects.create(title='平凡的世界',price=999.99,publish_id=1)
针对一对多,插入数据也可以填写表中的类中字段名
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.create(title='水浒传',price=555.22,publish=publish_obj)
方法1:publish_id=1 给实际字段添加关联数据值
方法2:publish=publish_obj 使用外键虚拟字段添加数据对象 一对多和一对一方法一致,可传对象可传值

2.多对多

add()
添加数据,括号内可以填写数字值,也可以填写数据对象
book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.add(1) # 在第三张关系表中给当前书籍绑定作者
remove()
删除数据 括号内可以填写数字值,也可以填写数据对象
book_obj.authors.remove(2)
book_obj.authors.remove(1, 3)
book_obj.authors.remove(author_obj1,)
book_obj.authors.remove(author_obj1,author_obj2)
set()
修改数据 括号内必须是可迭代对象
book_obj.authors.set((author_obj1,))
book_obj.authors.set((author_obj1, author_obj2))
clear()
清空数据 括号内不需要填写任何参数
book_obj.authors.clear()

六、多表查询

1.正反向的概念

正反向的概念核心就在于外键字段在谁的手上
正向查询
由外键字段所在的表数据查询关联的表数据 正向
反向查询
没有外键字段的表数据查询关联的表数据 反向
ps:正反向的核心就看外键字段在不在当前数据所在的表中
正向查询按外键字段,反向查询按表名小写

2、基于对象的跨表查询(子查询)

'''基于对象的跨表查询:子查询 分步操作'''
1.查询主键为1的书籍对应的出版社名称
# 先根据条件获取数据对象
book_obj = models.Book.objects.filter(pk=1).first()
# 再判断正反向的概念 由书查出版社 外键字段在书所在的表中 所以是正向查询
print(book_obj.publish.name) 2.查询主键为4的书籍对应的作者姓名
# 先根据条件获取数据对象
book_obj = models.Book.objects.filter(pk=4).first()
# 再判断正反向的概念 由书查作者 外键字段在书所在的表中 所以是正向查询
print(book_obj.authors) # app01.Author.None
print(book_obj.authors.all())
print(book_obj.authors.all().values('name')) # 3.查询jason的电话号码
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.author_detail.phone) # 4.查询北方出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='北方出版社').first()
print(publish_obj.book_set) # app01.Book.None
print(publish_obj.book_set.all()) # 5.查询jason写过的书籍
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set) # app01.Book.None
print(author_obj.book_set.all()) # 6.查询电话号码是110的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(author_detail_obj.author)
print(author_detail_obj.author.name)
'''基于双下划线的跨表查询'''
1.查询主键为1的书籍对应的出版社名称
res = models.Book.objects.filter(pk=1).values('publish__name','title')
print(res) # 2.查询主键为4的书籍对应的作者姓名
res = models.Book.objects.filter(pk=4).values('title', 'authors__name')
print(res) 3.查询jason的电话号码
res = models.Author.objects.filter(name='jason').values('author_detail__phone')
print(res) # 4.查询北方出版社出版过的书籍名称和价格
res = models.Publish.objects.filter(name='北方出版社').values('book__title','book__price','name')
print(res) # 5.查询jason写过的书籍名称
res = models.Author.objects.filter(name='jason').values('book__title', 'name')
print(res) # 6.查询电话号码是110的作者姓名
res = models.AuthorDetail.objects.filter(phone=110).values('phone', 'author__name')
print(res) # 1.查询主键为1的书籍对应的出版社名称
res = models.Publish.objects.filter(book__pk=1).values('name')
print(res)
# 2.查询主键为4的书籍对应的作者姓名
res = models.Author.objects.filter(book__pk=4).values('name','book__title')
print(res)
# 3.查询jason的电话号码
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone')
print(res)
# 4.查询北方出版社出版过的书籍名称和价格
res = models.Book.objects.filter(publish__name='北方出版社').values('title','price')
print(res)
# 5.查询jason写过的书籍名称
res = models.Book.objects.filter(authors__name='jason').values('title')
print(res)
# 6.查询电话号码是110的作者姓名
res = models.Author.objects.filter(author_detail__phone=110).values('name')
print(res)
进阶题:
# 查询主键为4的书籍对应的作者的电话号码
res = models.Book.objects.filter(pk=4).values('authors__author_detail__phone')
print(res)
res = models.AuthorDetail.objects.filter(author__book__pk=4).values('phone')
print(res)
res = models.Author.objects.filter(book__pk=4).values('author_detail__phone')
print(res)
表关系为一对多或者多对多时,需要.all()查询,不然会返回结果None
表关系为一对多或者多对多且是反向概念时,需要使用:对象.表名小写_set.all()
一对一表时,正向概念是外键字段,反向概念就是表名小写

ORM执行SQL语句,神奇的双下划线查询,ORM外键字段的创建,外键字段数据的操作,多表查询的更多相关文章

  1. 模型层字段-多表查询-神奇的双下划线查询-F,Q查询

    Django ORM中常用的字段和参数 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. In ...

  2. Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询

    Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...

  3. Python--day69--单表查询之神奇的双下划线

    单表查询之神奇的双下划线: 单表查询之神奇的双下划线 models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 models. ...

  4. django 神奇的双下划线,通过外键的三种查询方式

    一,用于跨表操作 只要是object后面字符串都是用双下划线__.其它地方用点. 如:的values中的group_code__name.group_code是一个外键 def list(reques ...

  5. Django之单表查询——神奇的双下划线

    1.filter中的单表查询 # 查询id>1且id<4的结果 ret = models.Person.objects.filter(id__gt=1,id__lt=4) print(re ...

  6. ORM( ORM查询13种方法3. 单表的双下划线的使用 4. 外键的方法 5. 多对多的方法 ,聚合,分组,F查询,Q查询,事务 )

    必知必会13条 <1> all(): 查询所有结果 <2> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或 ...

  7. Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段

    单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...

  8. 测试脚本配置、ORM必知必会13条、双下划线查询、一对多外键关系、多对多外键关系、多表查询

    测试脚本配置 ''' 当你只是想测试django中的某一个文件内容 那么你可以不用书写前后端交互的形式而是直接写一个测试脚本即可 脚本代码无论是写在应用下的test.py还是单独开设py文件都可以 ' ...

  9. django基础之day04,必知必会13条,双下划线查询,字段增删改查,对象的跨表查询,双下划线的跨表查询

    from django.test import TestCase # Create your tests here. import os import sys if __name__ == " ...

  10. Django--filter()-字段查找(双下划线的使用详解)

    Django--filter()-字段查找(双下划线的使用详解) 在了解django中的字段查找的同时,让我们先熟悉一下比较符: 大于--gt-(greater than) 小于--lt-(less ...

随机推荐

  1. 蓝桥杯赛前复习C++

    C标准库常用函数 memset函数:暴力清空 void *memset(void *str, int c, size_t n) str -- 指向要填充的内存块. c -- 要被设置的值.该值以 in ...

  2. letcode-学习-数组去重

    数组去重 问题描述: 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度.元素的 相对顺序 应该保持 一致 . 由于在某些语言中不 ...

  3. Python基础部分:11、文件和光标移动

    目录 一.文件操作 1.文件的概念 2.代码打开文件的方式 二.文件读写模式 1.'r' 只读模式 read 2.'w' 只写模式 write 3.'a' 尾部追写模式 add 三.文件操作模式 1. ...

  4. Docker基础和常用命令

    Docker基础和常用命令 一,Docker 简介 1.1,什么是 Docker Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,nam ...

  5. FHE学习笔记 #2 多项式环

    https://en.wikipedia.org/wiki/Polynomial_ring https://zhuanlan.zhihu.com/p/419266064 这篇知乎文章讲的比较透彻,但是 ...

  6. Seata 1.5.2 源码学习

    文章有点长,我决定用半个小时来给您分享~ 基于Seata 1.5.2,项目中用 seata-spring-boot-starter 1. SeataDataSourceAutoConfiguratio ...

  7. 如何开发Vite3插件构建Electron开发环境

    新用户购买<Electron + Vue 3 桌面应用开发>,加小册专属微信群,参与群抽奖,送<深入浅出Electron>.<Electron实战>作者签名版. 1 ...

  8. vue3中的defineProps,watch,computed

    在vue3的setup语法糖中,defineProps不需要引入了 <script setup> import { computed } from '@vue/reactivity'; i ...

  9. Ant Design Pro:Layout 组件——嵌套布局

    在   BasicLayout.jsx   文件中修改 <ProLayout layout="topmenu" className="chenshuai2144&q ...

  10. C温故补缺(三):存储类声明符(auto,register,extern,static)

    auto,register,extern,static 四个存储类声明符,用于定义变量/函数的作用域和声明周期 ① auto:自动变量,即普通变量,在平时定义变量时会自动赋予其auto类型 被auto ...