django基础之day04知识点----查询相关
from django.test import TestCase
# Create your tests here.
'''
当你想单独测试django中某一个py文件时,你需要手动配置测试文件
在manage.py文件中拷贝前四行代码,另外再加三行代码
添加:
import django
django.setup()
from app01 import models
'''
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
import django
django.setup()
from app01 import models
####################add增、set改、remove移除、clear清空四个方法的使用###################
# 一对多字段数据的增删改查
# 增
# models.Book.objects.create(title='三国演义',price=222.33,publish_id=1)
'''
方法:
第一种.传实际字段,利用publish_id=1,直接传表里面的实际字段,对应更新到数据库中
第二种.虚拟字段传数据对象,通过虚拟字段,利用对象来创建
'''
# publish_obj=models.Publish.objects.filter(pk=2).first()
# models.Book.objects.create(title='红楼梦',price=444.33,publish=publish_obj)
# 查
# 改
# 第一种 传实际字段
# models.Book.objects.filter(pk=1).update(publish_id=2)
# django中默认id作为主键,此处代表查询主键id=1的数据,pk=1 等同于 id=1
# update(表中字段A = 字段值B)
# 第二种 虚拟字段传数据对象
# publish_obj=models.Publish.objects.filter(pk=1).first()
# models.Book.objects.filter(pk=1).update(publish=publish_obj)
# 删 (知道即可,工作中不要使用)
# 默认的是级联删除、级联更新
# models.Publish.objects.filter(pk=3).delete()
# 多对多字段数据的增删改查
# 增(add)
# 方法一:(传数字)
# 方法二:(传对象)
# book_obj=models.Book.objects.filter(pk=2).first()
# 给当前这一本书绑定作者
# 1.手动添加---绝对不推荐
# 2.通过对象点属性【自我理解为:对象点虚拟字段-->直接进入第三张表】-->跨到第三张表
# print(book_obj.publish) #北方出版社
# print(book_obj.authors) #app01.Author.None
# book_obj.authors.add(1) #在第三张表里面给书籍id=2的添加一个author_id=1 的作者
# 【自我理解为:对象点虚拟字段-->是直接进入第三张表】
'''
结果就是:
id book_id author_id
1 2 1
'''
# book_obj.authors.add(1,2) #在第三张表里面给书籍id=2的添加两个作者,
# 一个是author_id=1的作者,另一个是author_id=2的作者
'''
结果就是:
id book_id author_id
1 2 1
2 2 2
'''
# book_obj = models.Book.objects.filter(pk=2).first()
# author_obj=models.Author.objects.filter(pk=1).first()
# author_obj1=models.Author.objects.filter(pk=2).first()
# # book_obj.authors.add(author_obj)
# book_obj.authors.add(author_obj,author_obj1)
'''
方法一:(传数字)
add方法 能够朝第三张关系表添加数据
即支持传数字
add(1,2)
也支持传对象
add(author_obj,author_obj100)
并且无论是传数字还是传对象都是可以传多个值
'''
'''
方法二:(传对象)
book_obj = models.Book.objects.filter(pk=2).first()
author_obj=models.Author.objects.filter(pk=1).first()
book_obj.authors.add(author_obj)
# 【第三句自我理解为:对象点虚拟字段-->是直接进入到第三张表关系表】
book_obj.authors.add(author_obj)
这里面是通过book_obj对象点Book表中的虚拟字段authors,直接进入到
第三张书籍与作者的book_authors关系表,然后添加了Author作者表
pk为1的对象
对于Book表中虚拟字段authors最通俗的介绍就是:牵线红娘
帅哥 通过红娘(authors) 美女
单身 ------------------------> 漂亮
单身帅哥book_obj通过通过红娘(authors添加了(add)漂亮美女,组成了一个家庭。
结果就是:
id book_id author_id
1 2 1
'''
# 改(set,注意set(这里还有一个括号()))
#方法一:传数字
#方法二:(传对象)
# 方法一:传数字
# book_obj=models.Book.objects.filter(pk=2).first()
# book_obj.authors.set((1,3))
'''
TypeError: set() takes 2 positional arguments but 3 were given
set()必须是一个可以迭代的对象,可以迭代的对象有:元祖、列表、字典、集合、字符串
使用set其实是先在数据库中删除对应的数据,然后再增加对应的数据
set()----set里面必须得传一个可以迭代的对象,不然会报错,
例如:book_obj.authors.set(1)
TypeError:'int' object is not iterable
整形不是可以迭代的对象
book_obj=models.Book.objects.filter(pk=2).first()
book_obj.authors.set('33')
如果set字符串33的话,
表中的数据只有一个结果,就是除了author_id=3的,
别的(author_id=1和author_id=2)都没了,
结果就是:
id book_id author_id
1 2 3
**********************************************************
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.set((1, 3))
# 在第三张表里面给书籍book_id=2的字段【重新设置】两个作者id,
# 一个是author_id=1的作者,另一个是author_id=2的作者
# 该方法有漏洞,如果book_id=2对应的作者id有5个,那么set((1,3)),
# 就会出问题了,一旦执行代码,
就会把book_id=2对应的author_id=2和author_id=4,和author_id=5的数据删除掉
'''
# book_obj = models.Book.objects.filter(pk=2).first()
# book_obj.authors.set((1, 3))
# 方法二:(传对象)
# book_obj=models.Book.objects.filter(pk=2).first()
#
# author_obj01=models.Author.objects.filter(pk=1).first()
# author_obj02=models.Author.objects.filter(pk=2).first()
# book_obj.authors.set((author_obj01,author_obj02))
#
'''
set修改多对多关系表中的数据
既可以传数字也可以传对象
但是需要注意的是括号内必须是可迭代对象
同样都支持多个数字和对象
set((1,3))
set((author_obj,author_obj02))
'''
#删除
#移除一个
#在book_authors表中移除author_id=1的数据
# book_obj=models.Book.objects.filter(pk=2).first()
# book_obj.authors.remove(1)
'''
结果就是:
id book_id author_id
1 2 2
'''
#移除多个
# book_obj=models.Book.objects.filter(pk=2).first()
# book_obj.authors.remove(1,2)
'''
结果就是:
id book_id author_id
1 2 3
'''
#传单个对象
# book_obj=models.Book.objects.filter(pk=2).first()
# author_obj01=models.Author.objects.filter(pk=1).first()
# author_obj02=models.Author.objects.filter(pk=2).first()
# book_obj.authors.remove(author_obj01)
#传多个对象
# book_obj.authors.remove(author_obj01,author_obj02)
'''
remove 既可以传数字,也可以传对象
并且都支持传多个值,不需要迭代
remove(1,2)
remove(author_obj01,author_02)
'''
#清空表数据 删除某个数据在第三张表中的所有记录
# book_obj=models.Book.objects.filter(pk=2).first()
# book_obj.authors.clear()
'''
clear 清空书籍相关所有记录,括号内不需要传任何参数。
'''
############################ 跨表查询##############################
#------------------情况01.基于对象的跨表查询----对应MySQL中的子查询,【子查询,分步操作】
# 什么是子查询,就是将一张表的查询结果,作为另一张表的查询条件
'''
正反向查询:
A表(有外键关联到B表) B表
关系字段在谁哪?由谁查谁就是正向,
关系字段在A那,由A查B是正向----称之为正向查询
由B查A是反向-----称之为反向查询
正向查询按字段
反向查询按表名小写_set
'''
#1.查询书籍主键为2的出版社名称
# 书查出版社是正向查询,按字段
# book_obj=models.Book.objects.filter(pk=2).first()
# print(book_obj.publish) # 出版社对象
# print(book_obj.publish.name) # 打印结果:北方出版社
#2.查询书籍主键为4的作者姓名
# 书查作者是正向查询,按字段
# book_obj=models.Book.objects.filter(pk=4).first()
# print(book_obj.authors) #标志性结果app01.Author.None,不代表代码错误,仅仅是少了一个 .all()
# print(book_obj.authors.all()) #<QuerySet [<Author: oscar>, <Author: egon>]>
#3.查询作者是jason的手机号码
# #这个是问题代码,原因是由于在models中的Author表建立表与表关系的时候,写错了一个单词
# author_obj=models.Author.objects.filter(name='jason').first()
# res = models.Author.objects.filter(name='jason')
# print(author_obj)
# print(author_obj.author_detail.phone) #结果:110
'''
什么时候需要加all
当正向查询点击外键字段数据有多个的情况下,需要 .all()比如,一本书多个作者
当反向查询点击表名小写_set之后有多个值的情况下,需要 .all() 查询所有
标志性结果app01.Author.None 一旦看到该结果,只需要加.all()即可
在写orm语句的时候,跟你写sql语句一样,不要想着一次性写完,
写一点差一点再写一点
'''
#4.查询出版社是东方出版社出版过的书籍,并且打印书籍的名称
# 通过出版社查书籍是反向查询,反向查询表名小写_set
# publish_obj=models.Publish.objects.filter(name='东方出版社').first()
# print(publish_obj.book_set) #app01.Book.None
# print(publish_obj.book_set.all()) #<QuerySet [<Book: Book object>, <Book: Book object>]>
# book=publish_obj.book_set.all() #<QuerySet [<Book: Book object>, <Book: Book object>]>
#QuerySet,用for循环取列表中的对象,通过print(对象.属性),获取对应的值
# for i in book:
# print(i.title) #三国演义、水浒传
#5.查询作者是jason写过的书籍
# 通过作者查书籍是反向查询,反向查询表名小写_set
# author_obj=models.Author.objects.filter(name='jason').first()
# print(author_obj.book_set) #app01.Book.None
# print(author_obj.book_set.all()) #<QuerySet [<Book: Book object>, <Book: Book object>]>
#6.查询手机号是120的作者姓名
#作者详情查作者,反向查询,表名小写_set
# author_detail_obj=models.AuthorDetail.objects.filter(phone=120).first()
# print(author_detail_obj.author)
# print(author_detail_obj.author.email) #444@qq.com
# print(author_detail_obj.author.name) #oscar
'''
反向查询 :
什么时候表名加 _set,总结:
当你反向查询的数据是多个的时候就需要表名加上 _set,
当你反向查询的数据是一个的时候就不需要加 _set
专业总结术语如下:
查询的表关系中外键上书写的是 一对多、多对多的情况需要加 _set
查询的表关系中外键上书写的是一对一,这种情况不需要加 _set
一对多:ForeignKey (django中没有OneToManyField)
多对多:ManyToManyField
一对一:OneToOneField
'''
#---------------------情况02.基于双下划线的跨表查询 联表操作
'''
inner join
left join
right join
union
'''
#***************双下划线的跨表查询**************重点中的重点优先掌握************************
'''
values方法总结:
values('publish__name')
values中写外键字段就相当于已经跨到了外键字段所关联的表
你想要该表中的哪个字段,只需要双下字段名(__name)获取即可
'''
#1.查询书籍pk为2的出版社名称
# 正向
# res=models.Book.objects.filter(pk=2).values('publish__name')
# values中publish一写,就代表已经跳转到了Publish这张表,然后双下name来取字段的值
#需要注意的是values里面有引号,自己总是忘记写
# print(res) #<QuerySet [{'publish__name': '北方出版社'}]>
''' filter()括号里面既支持正向,同时也支持反向 '''
# 反向
# print(models.Publish.objects.filter(book__pk=2)) #<QuerySet [<Publish: 北方出版社>]>
# res=models.Publish.objects.filter(book__pk=2).values('name')
# print(res) #<QuerySet [{'name': '北方出版社'}]>
#2.查询书籍pk为2的作者姓名
# 正向
# res=models.Book.objects.filter(pk=2).values('authors__name')
# print(res) #<QuerySet [{'authors__name': 'jason'}, {'authors__name': 'oscar'}]>
# 查询书籍pk为2的作者姓名和邮箱
# res=models.Book.objects.filter(pk=2).values('authors__name','authors__email')
# print(res)
#打印结果<QuerySet [{'authors__name': 'jason', 'authors__email': '123@qq.com'}, {'authors__name': 'oscar', 'authors__email': '444@qq.com'}]>
# 反向
# res=models.Author.objects.filter(book__pk=2).values('name')
# print(res) #<QuerySet [{'name': 'jason'}, {'name': 'oscar'}]>
#
# res=models.Author.objects.filter(book__pk=2).values('name','email')
# print(res)
#打印结果<QuerySet [{'name': 'jason', 'email': '123@qq.com'}, {'name': 'oscar', 'email': '444@qq.com'}]>
#3.查询作者是egon的家庭地址
# 正向
# res=models.Author.objects.filter(name='egon').values('author_detail__addr')
# print(res) #<QuerySet [{'author_detail__addr': '山东'}]>
# 反向
# res=models.AuthorDetail.objects.filter(author__name='egon').values('addr')
# print(res) #<QuerySet [{'addr': '山东'}]>
#4.查询出版社是东方出版社出版过的书的名字
# 正向
# res=models.Publish.objects.filter(name='东方出版社').values('book__title')
# print(res) #<QuerySet [{'book__title': '三国演义'}, {'book__title': '水浒传'}]>
# 反向
# res=models.Book.objects.filter(publish__name='东方出版社').values('title')
# print(res) #<QuerySet [{'title': '三国演义'}, {'title': '水浒传'}]>
#最复杂之orm查询,查询书籍pk=2的作者的手机号
# 正向
# res=models.Book.objects.filter(pk=2).values('authors__author_detail__phone')
# print(res) #<QuerySet [{'authors__author_detail__phone': 110}, {'authors__author_detail__phone': 120}]>
# 反向
# res=models.Author.objects.filter(book__pk=2).values('author_detail__phone')
# print(res)
#打印结果:<QuerySet [{'author_detail__phone': 110}, {'author_detail__phone': 120}]>
django基础之day04知识点----查询相关的更多相关文章
- django基础知识之模型查询:
查询集表示从数据库中获取的对象集合 查询集可以含有零个.一个或多个过滤器 过滤器基于所给的参数限制查询的结果 从Sql的角度,查询集和select语句等价,过滤器像where和limit子句 接下来主 ...
- django基础之day04,聚合查询和分组查询
聚合查询: 聚合函数必须用在分组之后,没有分组其实默认整体就是一组 Max Min Sum Avg Count 1.分组的关键字是:aggretate 2.导入模块 from django.db.mo ...
- django基础之day04,必知必会13条,双下划线查询,字段增删改查,对象的跨表查询,双下划线的跨表查询
from django.test import TestCase # Create your tests here. import os import sys if __name__ == " ...
- python&django 实现页面中关联查询小功能(基础篇)
效果 实现效果图如下,根据过滤条件查询相关信息. 知识点 1.配置URL,在路由中使用正则表达式 2.过滤查询 代码 setting.py from django.contrib import adm ...
- Django ORM --- 建表、查询、删除基础
1.什么是ORM ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的 ...
- Django 07 Django模型基础2 (常用查询和多表关联)
Django 07 Django模型基础2 (常用查询和多表关联) 一.常用查询 #查找数据 def search_user(request): #获取 rs = User.objects.first ...
- django基础之day05,F与Q查询,Q查询的高级用法
#F与Q查询 #*************************** F 查询 ******************** # F 查询数据库中的其他字段!!! #1.查询库存数大于卖出数的书籍 fr ...
- Web框架之Django_01初识(三大主流web框架、Django安装、Django项目创建方式及其相关配置、Django基础三件套:HttpResponse、render、redirect)
摘要: Web框架概述 Django简介 Django项目创建 Django基础必备三件套(HttpResponse.render.redirect) 一.Web框架概述: Python三大主流Web ...
- 关于mysql,需要掌握的基础(一):CRUD、存储引擎、单表查询相关、多表查询join、事务并发、权限管理等等
目录 关于mysql,需要掌握的基础(一): 1.了解数据库sql.数据库系统.数据库管理系统的概念. 2.了解DDL.DML.DQL语句是什么? 3.了解存储引擎.存储引擎[InnoDB 和 MyI ...
随机推荐
- 前端页面传来数组,后台用对象集合list接收数据的写法
//保存页面显示应用$("#save").click(function(){ var data = [{"applicationtypeid":"65 ...
- router-link传递参数
有个功能: 依据传入值,跳到产品详情页,但是详情页的内容依据传入值来相应变化. 如果使用点击事件@clic来实现,则有三个重复的跳转代码. 避免多次定义重复函数,可以使用router-link 传参数 ...
- 微博验证码的识别并登录获取cookies
记得以前微博是用的宫格验证码,现在不一样了,用的是滑块验证码和 点触验证码,每天登陆的第一次基本用的是滑块,继续登录就都用的是点触验证码.所以滑块验证码不写,感兴趣的可以补上. 代码: 这里用的超级鹰 ...
- TensorFlow2.0极简安装(亲测有效)
x相信每一个学习深度学习的人来说都知道Google的深度学习框架TensorFlow,估计每个人都想成为一个TF Boy(TensorFlow Boy).我也是这个想法,于是我踏上了安装TensorF ...
- 打算写一个《重学Node.js》系列,希望大家多多支持
先放上链接吧,项目已经开始2周了:https://github.com/hellozhangran/happy-egg-server 想法 现在是2019年11月24日,还有人要开始学习Node.js ...
- Redis高可用演进(一)
原文链接:http://www.cnblogs.com/chenty/p/5152878.html 最近整理Redis,对sentinel有了更深入的理解,特地总结如下 1.主从Redis 主从red ...
- 【开发工具 - MySQL】之不能插入中文的问题
新安装的MySQL数据库,在安装的时候设置了字体为UTF8,但在使用insert语句插入中文的时候还是会报错. 具体解决方法:在MySQL控制台中输入以下设置代码: SET character_set ...
- 源码安装php7.2
`# 安装依赖包 yum install -y gcc gcc-c++ make zlib zlib-devel pcre pcre-devel \ libjpeg libjpeg-devel lib ...
- vue使用tips
1. native修饰符可以用来绑定原生事件 2. destroyed在列表重渲染时,销毁的列表项会调用. 3. 并不是所有的数据都适合放入vuex 4. 子组件mounted先于父组件发生. 5. ...
- 补习系列(20)-大话 WebSocket 与 "尬聊"的实现
目录 一.聊聊 WebSocket 二.Stomp 是个什么鬼 三.SpringBoot 整合 WebSocket A. 引入依赖 B. WebSocket 配置 C. 控制器 D. 前端实现 四.参 ...