ORM中基于对象查询与基于queryset查询
感谢老男孩~ 一步一步走下去
前面是视图函数 后面是表结构models.py
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse # Create your views here.
from app01 import models def query(request):
#########基于对象查询(子查询)########### # 一对多 book(publish forkey) ---> publish 正向查询
# 正向查询 按字段
# 反向查询 表名_set.all() 一对多
# 查询python这本书籍的出版社的邮箱
python = models.Book.objects.filter(title="python").first() # 对象
print(python.publish.email) # 查询苹果出版社出版的书籍名称 (反向查询 表名小写_set.all())
# publish_obj = models.Publish.objects.filter(name="苹果出版社").first() #对象
# print(publish_obj)
# for obj in publish_obj.book_set.all():
# print(obj.title) # 按字段(author.all())
# 多对多 book ---------> author
# <---------
# book_set.all() # 正向查询
# 查询python的作者的年龄
# python = models.Book.objects.filter(title="python").first()
# for author in python.authors.all():
# print(author.name,author.age) # 反向查询
# 查询alex出版过的书籍名称
# alex = models.Author.objects.filter(name="alex").first()
# for book in alex.book_set.all():
# print(book.title) # 一对一 按字段authorDetail
# author -----------> authordetail
# <------------
# 按表名 author
# 查询alex的手机号 (正向查询)
# alex = models.Author.objects.filter(name="alex").first()
# print(alex.authorDetail.telephone) # 查询家在北京的作者名字 (反向查询)
# obj = models.AuthorDetail.objects.filter(addr="北京").first()
# print(obj.author.name) print("分割线:", "*" * ) # 如果addr为北京的人很多 执行了若干次的一对一执行
# obj_list = models.AuthorDetail.objects.filter(addr="北京").all()
# for first in obj_list:
# print(first.author.name)
"""
查询python这本书籍的出版社的邮箱 models.book.objects.filter(title="python").first().publish.email
第一步: SELECT "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price
", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."title" = 'python' ORDER BY "app01_boo
k"."nid" ASC LIMIT 1; args=('python',)
第二步:SELECT "app01_publish"."nid", "app01_publish"."name", "app01_publish"."city", "app01_publish"."e
mail" FROM "app01_publish" WHERE "app01_publish"."nid" = 1; args=(1,)
即: #若干条子查询 select语句
select publish_id from Book where title = "python"
select email from Publish where nid = 查询alex手机号 models.author.objects.filter(name="alex").first().authorDetail.telephone
select authorDetail_id from author where name = "alex"
select telephone from authordetail where nid = """ #########基于queryset和__查询 (join)###########
# 正向查询:按字段__
# 反向查询:表名小写__
"""
查询python 这本书籍的出版社的邮箱
select publish.email from Book left join Publish on book.publish_id = publish.nid where book.title = "python"
"""
# 查询python 这本书籍的出版社的邮箱 (正向查询)
ret = models.Book.objects.filter(title="python").values("publish__email")
#方式2
models.Publish.objects.filter(book__title="python").values("email")
print(ret.query) # ret.query属性 就不需要在setging设置全局了
"""
SELECT "app01_publish"."email" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "ap
p01_book"."title" = python """ #查询苹果出版社的书籍名称
#方式1
book = models.Publish.objects.filter(name="天空出版社").values("book__title")
print(book.query)
#方式2
book = models.Book.objects.filter(publish__name="天空出版社").values("title")
print(book.query)
"""
SELECT "app01_book"."title" FROM "app01_publish"
LEFT OUTER JOIN "app01_book" ON ("app01_publish"."nid" = "app01_book"."publish_id")
WHERE "app01_publish"."name" = 天空出版社 SELECT "app01_book"."title" FROM "app01_publish"
LEFT OUTER JOIN "app01_book" ON ("app01_book"."publish_id" = "app01_publish"."nid")
WHERE "app01_publish"."name" = 天空出版社 """ #查询alex的手机号
alex = models.Author.objects.filter(name="alex").values("authorDetail__telephone")
print(alex)
alex = list(alex)
print(alex)
tel = models.AuthorDetail.objects.filter(author__name="alex").values("telephone")
print(tel) #查询手机号以151开头的作者出版过的书籍名称以及对应的出版社名称 (五张表)
book_ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="").values("title","publish__name")
print(book_ret)
publish_ret = models.Publish.objects.filter(book__authors__authorDetail__telephone__startswith="").values("book__title","name")
print(publish_ret)
"""
SELECT "app01_book"."titl
e", "app01_publish"."name" FROM "app01_book" INNER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id") INNER
JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."nid") INNER JOIN "app01_authordetail" ON ("app01_author"."authorD
etail_id" = "app01_authordetail"."nid") INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_autho
rdetail"."telephone" LIKE 151% ESCAPE '\'
"""
# test查询手机号以151开头的作者出版过的书籍名称以及对应的出版社名称 (五张表)
book = models.Book.objects.filter(authors__authorDetail__telephone__startswith="").values("title","publish__name")
publish = models.Publish.objects.filter(book__authors__authorDetail__telephone__startswith="").values("book__title","name")
print("this is test",book,publish) ###############################聚合与分组#####################################
#查询所有书籍的价格和
from django.db.models import Sum, Count, Avg
ret = models.Book.objects.all().aggregate(price_sum = Sum("price"))
print(ret) #ret为字典 {'price_sum': Decimal('710.00')} #查询所有作者的平均年龄
ret = models.Author.objects.all().aggregate(age_avg = Avg("age"))
print(ret) #统计有多少个作者
ret = models.Author.objects.all().aggregate(num = Count("nid"))
print(ret) #分组
"""
sql分组
emp表
id name age dep
alex 技术部
egon 技术部
wenzhou 运营部
jc 运营部 查询每一个部门的人数
sql:
select Count(id) from emp group by dep
orm:
models.emp.objects.values("dep").annotate(c=Count("id")) emp表
id name age dep_id
alex
egon
wenzhou dep表
id name
技术部
运营部 查询每一个部门名称以及对应人数
sql:
select * from emp inner join dep on emp.dep_id = dep.id
id name age dep_id dep.id dep.name
alex 技术部
egon 运营部
wenzhou 运营部
select dep.name, Count(*) from emp inner join dep on emp.dep_id = dep.id group by dep.id, dep.name ORM:
关键点:
.queryset数据可以调用annotate()
.annotate进行分组统计,按照前面的select的字段进行group by
.annotate()返回值依然是queryset对象, 增加了分组统计的键值对
models.dep.objects.values("name").annotate(c=Count("emp__name")).values("name","c")
models.emp.objects.values("dep__name").annotate(c=Count("name")).values("dep__name", "c")
select dep.name, Count(emp.name) as c from dep inner join emp on .. group by dep.name select ___ from ___ inner join ___ on ... group by ___
"""
ret = models.Publish.objects.values("name") #SELECT "app01_publish"."name" FROM "app01_publish"
print(ret.query) from django.db.models import Max
#查询每一个作者的名字以及出版过的书籍最高价格
ret = models.Author.objects.values("name").annotate(max_price = Max("book__price")).values("name","max_price")
print(ret) """
select author.name, Max(book.price) as max_price from author inner join book_authors on ...
inner join book on ...
group by author.name
""" #查询每一个出版社出版过的书籍的平均价格
ret = models.Publish.objects.values("name").annotate(avg_price = Avg("book__price")).values("name","avg_price")
print(ret) #查询每一本书籍的作者个数
ret = models.Book.objects.values("title").annotate(author_count = Count("authors__name")).values("title","author_count") #或者将authors__name换成authors
print(ret) #查询每一个分类的名称以及对应的文章数
# models.Category.objects.all().annotate(c = Count("article__title")).values("title","c") #统计不止2个作者的图书名称: 作者数大于两个 难点
#先统计每个本书籍的作者个数
ret = models.Book.objects.values("title").annotate(count=Count("authors__name")).values("title","count")
print(ret) """
select book.title, Count(author.name) as c from book inner join book-authors on ..
inner join author on ..
group by book.id having c >
"""
ret = models.Book.objects.values("title").annotate(count=Count("authors__name")).filter(count__gt=).values("title","count")
print(ret)
#统计作者为2的图书名称
ret = models.Book.objects.values("title").annotate(count=Count("authors__name")).filter(count=).values("title","count")
print(ret) #统计出版的每一本价格大于100的书籍
ret = models.Book.objects.values("title").filter(price__gt=).values("title","price")
print(ret) #统计每一个出版出版的书籍及价格
ret = models.Publish.objects.values("name").annotate(count=Count("book__title")).values("name","book__title")
print(ret) #统计每一个出版社出版的书籍个数
ret = models.Publish.objects.values("name").annotate(count=Count("book__title")).values("name","count")
print(ret) #统计每一个出版社出版大于100的书籍名称
ret = models.Publish.objects.values("name").annotate().filter(book__price__gt=).values("name","book__title","book__price")
print(ret)
return HttpResponse("ok")
from django.db import models # Create your models here.
from django.db import models # Create your models here. class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=)
age=models.IntegerField() # 与AuthorDetail建立一对一的关系
authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.BigIntegerField()
addr=models.CharField( max_length=) class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=)
city=models.CharField( max_length=)
email=models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=)
publishDate=models.DateField()
price=models.DecimalField(max_digits=,decimal_places=)
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author',) #多对多关联字段
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse # Create your views here.
from app01 import models def query(request):
#########基于对象查询(子查询)########### # 一对多 book(publish forkey) ---> publish 正向查询
# 正向查询 按字段
# 反向查询 表名_set.all() 一对多
# 查询python这本书籍的出版社的邮箱
python = models.Book.objects.filter(title="python").first() # 对象
print(python.publish.email) # 查询苹果出版社出版的书籍名称 (反向查询 表名小写_set.all())
# publish_obj = models.Publish.objects.filter(name="苹果出版社").first() #对象
# print(publish_obj)
# for obj in publish_obj.book_set.all():
# print(obj.title) # 按字段(author.all())
# 多对多 book ---------> author
# <---------
# book_set.all() # 正向查询
# 查询python的作者的年龄
# python = models.Book.objects.filter(title="python").first()
# for author in python.authors.all():
# print(author.name,author.age) # 反向查询
# 查询alex出版过的书籍名称
# alex = models.Author.objects.filter(name="alex").first()
# for book in alex.book_set.all():
# print(book.title) # 一对一 按字段authorDetail
# author -----------> authordetail
# <------------
# 按表名 author
# 查询alex的手机号 (正向查询)
# alex = models.Author.objects.filter(name="alex").first()
# print(alex.authorDetail.telephone) # 查询家在北京的作者名字 (反向查询)
# obj = models.AuthorDetail.objects.filter(addr="北京").first()
# print(obj.author.name) print("分割线:", "*" * ) # 如果addr为北京的人很多 执行了若干次的一对一执行
# obj_list = models.AuthorDetail.objects.filter(addr="北京").all()
# for first in obj_list:
# print(first.author.name)
"""
查询python这本书籍的出版社的邮箱 models.book.objects.filter(title="python").first().publish.email
第一步: SELECT "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price
", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."title" = 'python' ORDER BY "app01_boo
k"."nid" ASC LIMIT 1; args=('python',)
第二步:SELECT "app01_publish"."nid", "app01_publish"."name", "app01_publish"."city", "app01_publish"."e
mail" FROM "app01_publish" WHERE "app01_publish"."nid" = 1; args=(1,)
即: #若干条子查询 select语句
select publish_id from Book where title = "python"
select email from Publish where nid = 1 查询alex手机号 models.author.objects.filter(name="alex").first().authorDetail.telephone
select authorDetail_id from author where name = "alex"
select telephone from authordetail where nid = 1 """ #########基于queryset和__查询 (join)###########
# 正向查询:按字段__
# 反向查询:表名小写__
"""
查询python 这本书籍的出版社的邮箱
select publish.email from Book left join Publish on book.publish_id = publish.nid where book.title = "python"
"""
# 查询python 这本书籍的出版社的邮箱 (正向查询)
ret = models.Book.objects.filter(title="python").values("publish__email")
#方式2
models.Publish.objects.filter(book__title="python").values("email")
print(ret.query) # ret.query属性 就不需要在setging设置全局了
"""
SELECT "app01_publish"."email" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "ap
p01_book"."title" = python """ #查询苹果出版社的书籍名称
#方式1
book = models.Publish.objects.filter(name="苹果出版社").values("book__title")
print(book.query)
#方式2
book = models.Book.objects.filter(publish__name="苹果出版社").values("title")
print(book.query)
"""
SELECT "app01_book"."title" FROM "app01_publish"
LEFT OUTER JOIN "app01_book" ON ("app01_publish"."nid" = "app01_book"."publish_id")
WHERE "app01_publish"."name" = 苹果出版社 SELECT "app01_book"."title" FROM "app01_publish"
LEFT OUTER JOIN "app01_book" ON ("app01_book"."publish_id" = "app01_publish"."nid")
WHERE "app01_publish"."name" = 苹果出版社 """ #查询alex的手机号
alex = models.Author.objects.filter(name="alex").values("authorDetail__telephone")
print(alex)
alex = list(alex)
print(alex)
tel = models.AuthorDetail.objects.filter(author__name="alex").values("telephone")
print(tel) #查询手机号以151开头的作者出版过的书籍名称以及对应的出版社名称 (五张表)
book_ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values("title","publish__name")
print(book_ret)
publish_ret = models.Publish.objects.filter(book__authors__authorDetail__telephone__startswith="151").values("book__title","name")
print(publish_ret)
"""
SELECT "app01_book"."titl
e", "app01_publish"."name" FROM "app01_book" INNER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id") INNER
JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."nid") INNER JOIN "app01_authordetail" ON ("app01_author"."authorD
etail_id" = "app01_authordetail"."nid") INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_autho
rdetail"."telephone" LIKE 151% ESCAPE '\'
"""
# test查询手机号以151开头的作者出版过的书籍名称以及对应的出版社名称 (五张表)
book = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values("title","publish__name")
publish = models.Publish.objects.filter(book__authors__authorDetail__telephone__startswith="151").values("book__title","name")
print("this is test",book,publish) ###############################聚合与分组#####################################
#查询所有书籍的价格和
from django.db.models import Sum, Count, Avg
ret = models.Book.objects.all().aggregate(price_sum = Sum("price"))
print(ret) #ret为字典 {'price_sum': Decimal('710.00')} #查询所有作者的平均年龄
ret = models.Author.objects.all().aggregate(age_avg = Avg("age"))
print(ret) #统计有多少个作者
ret = models.Author.objects.all().aggregate(num = Count("nid"))
print(ret) #分组
"""
sql分组
emp表
id name age dep
1 alex 21 保安部
2 egon 23 保安部
3 wenzhou 25 保安部
4 jc 22 保安部 查询每一个部门的人数
sql:
select Count(id) from emp group by dep
orm:
models.emp.objects.values("dep").annotate(c=Count("id")) emp表
id name age dep_id
1 alex 21 1
2 egon 23 2
3 wenzhou 25 2 dep表
id name
1 保安部
2 保洁部 查询每一个部门名称以及对应人数
sql:
select * from emp inner join dep on emp.dep_id = dep.id
id name age dep_id dep.id dep.name
1 alex 21 1 1 保安部
2 egon 23 2 2 保洁部
3 wenzhou 25 2 2 保洁部
select dep.name, Count(*) from emp inner join dep on emp.dep_id = dep.id group by dep.id, dep.name ORM:
关键点:
1.queryset数据可以调用annotate()
2.annotate进行分组统计,按照前面的select的字段进行group by
3.annotate()返回值依然是queryset对象, 增加了分组统计的键值对
models.dep.objects.values("name").annotate(c=Count("emp__name")).values("name","c")
models.emp.objects.values("dep__name").annotate(c=Count("name")).values("dep__name", "c")
select dep.name, Count(emp.name) as c from dep inner join emp on .. group by dep.name select ___ from ___ inner join ___ on ... group by ___
"""
ret = models.Publish.objects.values("name") #SELECT "app01_publish"."name" FROM "app01_publish"
print(ret.query) from django.db.models import Max
#查询每一个作者的名字以及出版过的书籍最高价格
ret = models.Author.objects.values("name").annotate(max_price = Max("book__price")).values("name","max_price")
print(ret) """
select author.name, Max(book.price) as max_price from author inner join book_authors on ...
inner join book on ...
group by author.name
""" #查询每一个出版社出版过的书籍的平均价格
ret = models.Publish.objects.values("name").annotate(avg_price = Avg("book__price")).values("name","avg_price")
print(ret) #查询每一本书籍的作者个数
ret = models.Book.objects.values("title").annotate(author_count = Count("authors__name")).values("title","author_count") #或者将authors__name换成authors
print(ret) #查询每一个分类的名称以及对应的文章数
# models.Category.objects.all().annotate(c = Count("article__title")).values("title","c") #统计不止2个作者的图书名称: 作者数大于两个 难点
#先统计每个本书籍的作者个数
ret = models.Book.objects.values("title").annotate(count=Count("authors__name")).values("title","count")
print(ret) """
select book.title, Count(author.name) as c from book inner join book-authors on ..
inner join author on ..
group by book.id having c > 2
"""
ret = models.Book.objects.values("title").annotate(count=Count("authors__name")).filter(count__gt=).values("title","count")
print(ret)
#统计作者为2的图书名称
ret = models.Book.objects.values("title").annotate(count=Count("authors__name")).filter(count=).values("title","count")
print(ret) #统计出版的每一本价格大于100的书籍
ret = models.Book.objects.values("title").filter(price__gt=).values("title","price")
print(ret) #统计每一个出版出版的书籍及价格
ret = models.Publish.objects.values("name").annotate(count=Count("book__title")).values("name","book__title")
print(ret) #统计每一个出版社出版的书籍个数
ret = models.Publish.objects.values("name").annotate(count=Count("book__title")).values("name","count")
print(ret) #统计每一个出版社出版大于100的书籍名称
ret = models.Publish.objects.values("name").annotate().filter(book__price__gt=).values("name","book__title","book__price")
print(ret)
return HttpResponse("ok")
ORM中基于对象查询与基于queryset查询的更多相关文章
- Django ORM 之基于对象、双下划线查询
返回ORM目录 Django ORM 内容目录: 一. 基于对象的表查询 二. 基于双下划线的查询 三. 聚合查询 aggregate 四. 分组查询 annotate 一. 基于对象的表查询 1.正 ...
- django的orm中F对象的使用
今天不巧就用上了. 就是将数据库的字段,自增1的场景. from django.db.models import F DeployPool.objects.filter(name=deployvers ...
- [C++程序设计]基于对象的程序设计 基于对象的程序设计
1. 面向对象分析(object oriented analysis,OOA)2. 面向对象设计(object oriented design,OOD)3. 面向对象编程(object oriente ...
- C#ORM中的对象映射
使用Linq.Expressions来动态生成映射方法 1.我们先写个简单的类Test,包含一个ID和Name. public class Test { public int? ID { get; s ...
- Python学习---ORM查询之基于对象的正向/反向/聚合/分组/Q/F查询
ORM查询之基于对象的正向查询与反向查询 对象形式的查询 # 正向查询 ret1=models.Book.objects.first() print(ret1.title) print(ret1.pr ...
- django之 使用views.py里面的函数对表进行增删改查 内容(models.py中表的创建、views.py中函数的使用,基于对象的跨表查询)
models之对于表的创建有以下几种: 一对一:ForeignKey("Author",unique=True), OneToOneField("Author" ...
- ORM查询之基于对象的正向查询与反向查询
一.为什么有正向查询和反向查询? 举例有两张表,一张表叫书籍表,一张表叫出版社表,他们关系是一对多的关系,书籍是多,出版社是一,因为一本书应该只有一个出版社对应,而出版社可以有多本书对应. 那么在实际 ...
- orm多表的创建和基于对象的查询
创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系( ...
- 基于对象的orm跨表查询再练习
model.py from django.db import models # Create your models here. class Book(models.Model): nid = mod ...
随机推荐
- HDU 4259
虽然知道是置换,却很久没有思路.忽然想到,由初始状态A经过变换后回到A状态,应该是不停循环可重复的.于是,猜想数字的位置也是重复循环的.拿了个例子验证了一下,某然是这样.例如第二个10,3的例子有1- ...
- 模式匹配的KMP 算法
常见的字符串匹配时,模式串长度为n,源串长度为m,则从头匹配,两个指针i指向源串,j指向模式串,如遇到不同则回溯使j=0,这样就要反复匹配会使效率变低. 因为在如今i之前 的模式串与匹配串的匹配是同样 ...
- Vuejs2.0学习之二(Render函数,createElement,vm.$slots,函数化组件,模板编译,JSX)
时隔一周多,因为一些别的事情绊住了,下面接着写.中间这段时间也有看官方文档,发现正如他所说90%的基础内容都一样,所以这里直接跳到我比较关注的东东上,要是想看看哪些不一样,可以参考这个http://v ...
- apiCloud实现加载更多效果,基本完美~
apiCloud实现加载更多效果 1.接口支持,加入参数page. $page = $this->_request('page','trim','1'); $pagesize = 10; // ...
- 51nod 1649 齐头并进 (djikstra求最短路径,只用跑一次)
题目: 这道题有一个坑点:两种交通工具同时出发,中途不能停留在同一个小镇. 其实想通了就很简单,因为要么火车一步到达,要么汽车一步到达.不可能停留在同一个地方. 可是我还WA了好几次,蠢哭.想用BFS ...
- Servlet学习(五)——通过response设置响应体及中文乱码问题
1.响应体设置文本 PrintWriter writer=response.getWriter(); 获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲 ...
- sql 分割日期
datename(Year,CreateTime) ==2017 datename(Month,CreateTime) 7 1.获取星期(显示中文如:星期一) Select DateName( ...
- LCD中如何描绘点阵数据
下载软件“液晶汉字点阵zimo21” 描绘数据 打开软件后,新建图像-取模方式选择C51(A51和C51区别就是,A-F开头要加0,例如0x0AF)-模拟动画中放大格点-描绘图像-点阵生成区 对获得数 ...
- SpringCloud学习笔记(12)----Spring Cloud Netflix之Hystrix断路器的流程和原理
工作流程(参考:https://github.com/Netflix/Hystrix/wiki/How-it-Works) 1. 创建一个HystrixCommand或HystrixObservabl ...
- Intellij IDEA 2018.3激活破解方法(解决key is invalid)
1.程序安装包: https://download.jetbrains.8686c.com/idea/ideaIU-2018.3.exe 2.破解补丁:http://idea.lanyus.com/j ...