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 ...
随机推荐
- ubuntu server 1604 搭建FTP服务器
1.查看是否安装 ftp服务器vsftpd -v 2.安装ftp服务器sudo apt-get install vsftpd 3.如果安装失败或者配置出现问题,可以卸载 ftp服务器sudo apt- ...
- php为什么要用swoole?
最近两个月一直在研究 Swoole,那么借助这篇文章,我希望能够把 Swoole 安利给更多人.虽然 Swoole 可能目前定位是一些高级 phper 的玩具,让中低级望而生畏,可能对一些应用场景也一 ...
- springboot+swagger接口文档企业实践(上)
目录 1.引言 2.swagger简介 2.1 swagger 介绍 2.2 springfox.swagger与springboot 3. 使用springboot+swagger构建接口文档 3. ...
- The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in either web.xml or the jar files deployed with this application] with root cause异常处理及解释
1.问题描述: 在web的jsp文件中想用jstl这个标准库,在运行的时候很自然的引用jar包如下: <dependency> <groupId>javax.servlet.j ...
- Prometheus 【目录】
正在陆续更新,内容大体包括: rule.标签重置.cAdversior.自动发现(File 自动发现.DNS自动发现.k8s环境自动发现)等... 目录: prometheus[第一篇] Promet ...
- 简单实现TodoList
Todolist实例 储备知识js的splice的用法 实例逻辑 1 在data里面做一个存一条条留言的列表,往里面添加或者删除留言内容. 2 做一个变量和input双向绑定,然后做一个点击事件把这个 ...
- c语言l博客作业02
问题 答案 这个作业属于哪个课程 C语言程序设计l 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-2/homework/8687 我在这个 ...
- 【洛谷】P2256
(^_^) 题目: 题目 思路: 这是一道并查集水题,适合初学者做!!! 若不会并查集的点我,那是dalao的博客! 本题难点:名字是字符串,要字符串处理 给每个名字一个编号,如\(1,2,3,4,5 ...
- 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(8)- 从Serial(1-bit SPI) NOR恢复启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的1-bit SPI NOR恢复启动. 在前几篇里痞子衡介绍的Boot Device都属于主动启动的 ...
- MySql CPU彪高到百分之1000的排查思路
You need to enable JavaScript to run this app. 原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等情况,可查看当前链接:https:// ...