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 ...
随机推荐
- linux 正确的关机流程
查看系统的使用状态 1.使用who命令查看在线用户. 2.使用netstat -a或ss -tnl查看网络状态: 3.使用ps -aux 查看后台运行的程序. 通过上述操作可以了解系统目前使用状态,从 ...
- App自动化测试-1.App自动化介绍和环境搭建
App自动化测试-1.App自动化介绍和环境搭建 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-b ...
- 对 /langversion 无效;必须是 ISO-1、ISO-2、3、4、5 或 Default
反编译或者.net用更高版本打开时会出现这个问题,解决办法如下: 1.网页版程序,将解决方案中的Web.config中的 /langversion 的值改为指定的值,既可以解决,我这里采用的是默认值, ...
- 使用three.js创建大小不随着场景变化的文字
使用three.js创建大小不随着场景变化的文字,需要以下两步: 1.将文字绘制到画布上. 2.创建着色器材质,把文字放到三维场景中. 优点: 1.跟用html实现文字相比,这些文字可以被模型遮挡,更 ...
- Linux查看系统基本信息、版本信息等
Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号 1.uname -a (Linux查看版本当前操作系统内核信息) 2.cat /proc/version (L ...
- 关于python中的列表遍历注意事项
在开发过程中,很容易出现以下的错误: 可以看出:假如删除列表的元素之后直接执行continue,那么遍历的时候就会落下一个元素. 那么怎么解决这个问题呢? 首先 : 我们尝试把continue去掉: ...
- Nginx访问日志、日志切割、静态文件不记录日志和过期时间
6月8日任务 12.10 Nginx访问日志12.11 Nginx日志切割12.12 静态文件不记录日志和过期时间 12.10 Nginx访问日志 除了在主配置文件nginx.conf里定义日志格式外 ...
- 普通用户修改时间 sudo
sudo date neokylinV7.0 desktop 1.给/etc/sudoers加权限 # chmod u+w /etc/sudoers 2.添加配置 # vim /etc/sudoer ...
- PHP常用字符串函数总结
PHP语言中的字符串函数也是一个比较易懂的知识.今天我们就为大家总结了将近12种PHP字符串函数,希望对又需要的朋友有所帮助,增加读者朋友的PHP知识库. 1.查找字符位置函数 strpos($str ...
- 微信小程序——详细讲解页面传值(多种方法)
1.使用navigator的url带参传值 (1)在pageA页面有一个固定的值要传递到pageB页面,比如说一个固定的值user_id要传递给B <navigator url=".. ...