Python学习之路—2018/6/27

Python学习之路—2018/6/27

1.多表操作

添加记录

添加多对多关系

方式一:传入Author对象

book = Book.objects.get(bid=1)
gy = Author.objects.get(name="gy")
yq = Author.objects.get(name="yq")
book.authors.add(gy, yq)

运行结果:

方式二:传入Author主键

book = Book.objects.get(bid=2)
book.authors.add(3, 4)

运行结果:

移除多对多关系

book = Book.objects.get(bid=1)
book.authors.remove(2)  # 移除单个

运行结果:

book = Book.objects.get(bid=2)
book.authors.clear()  # 移除所有

运行结果:

2.跨表查询

跨表查询:

  1. 基于对象查询
  2. 基于双下划线查询
  3. 聚合和分组查询
  4. F与Q查询

基于对象

一对多查询(Book 与 Publish)

A—B,关联属性在A表中

正向查询:A----->B,通过字段查询

# 查询《坏蛋是怎样炼成的》这本书的出版社
>>> book = Book.objects.get(title="坏蛋是怎样炼成的")
>>> print(book.publish)
中国城市出版社

反向查询:B----->A,通过 表名(小写)_set.all()查询

# 查询中国城市出版社所有书籍
>>> publish = Publish.objects.get(name="中国城市出版社")
>>> book_list = publish.book_set.all()
>>> print(book_list)
<QuerySet [<Book: 坏蛋是怎样炼成的>, <Book: 斗罗大陆>]>

一对一查询(Author 与 AuthorDetail)

正向查询:

# 查询作者gy的电话号码
>>> gy = Author.objects.get(name="gy")
>>> print(gy.author_detail.telephone)
123

反向查询:通过表名

# 查询电话号码是456的作者名字
>>> author_detail = AuthorDetail.objects.get(telephone=456)
>>> print(author_detail.author.name)
yq

多对多查询(Book 与 Author)

正向查询:

# 查询《斗罗大陆》作者名字和生活的城市
>>> book_obj = Book.objects.get(title="斗罗大陆")
>>> authors = book_obj.authors.all()
>>> for i in authors:
        print(i.name, i.author_detail.addr)
糖加三勺 北京

反向查询:

# 查询天蚕土豆出过的书籍名字
>>> author = Author.objects.get(name="天蚕土豆")
>>> books = author.book_set.all()
>>> print(books)
<QuerySet [<Book: 斗破苍穹>]>

基于双下划线

一对多查询

正向查询:

# 查询《坏蛋是怎样炼成的》这本书的出版社
>>> Book.objects.filter(title="坏蛋是怎样炼成的").values("publish__name")
<QuerySet [{'publish__name': '中国城市出版社'}]>

反向查询:

# 查询《坏蛋是怎样炼成的》这本书的出版社
>>> Publish.objects.filter(book__title="坏蛋是怎样炼成的").values("name")
<QuerySet [{'publish__name': '中国城市出版社'}]>

多对多查询

正向查询:

# 查询《斗罗大陆》作者名字和生活的城市
>>> Book.objects.filter(title="斗罗大陆").values("authors__name",                         "authors__author_detail__addr")
<QuerySet [{'authors__name': '糖加三勺', 'authors__author_detail__addr': '北京'}]>

反向查询:

# 查询《斗罗大陆》作者名字和生活的城市
>>> Author.objects.filter(book__title="斗罗大陆").values("name",                         "author_detail__addr")
<QuerySet [{'name': '糖加三勺', 'author_detail__addr': '北京'}]>

一对一查询

正向查询

# 查询作者gy的电话号码
>>> Author.objects.filter(name="gy").values("author_detail__telephone")
<QuerySet [{'author_detail__telephone': 123}]>

反向查询

# 查询作者gy的电话号码
>>> ret5 = AuthorDetail.objects.filter(author__name="gy").values("telephone")
<QuerySet [{'telephone': 123}]>

连续跨表

正向查询

# 查询手机号以10开头的作者出版过的所有书籍名称以及出版社名称
>>>  Book.objects.filter(authors__author_detail__telephone__startswith=10).values("title",          "publish__name")       
<QuerySet [{'title': '斗破苍穹', 'publish__name': '武汉大学出版社'}, {'title': '武动乾坤', 'publish__name': '北京大学出版社'}]>

反向查询

# 查询手机号以10开头的作者出版过的所有书籍名称以及出版社名称
>>> Author.objects.filter(author_detail__telephone__startswith=10).values("book__title",           "book__publish__name")
<QuerySet [{'book__title': '斗破苍穹', 'book__publish__name': '武汉大学出版社'}, {'book__title': '武动乾坤', 'book__publish__name': '北京大学出版社'}]>

聚合查询

aggregate,返回值不再是queryset,而是字典

>>> from django.db.models import Avg, Max, Min, Count
>>> Book.objects.aggregate(Avg("price"), Max("price"), Min("price"), Count("price"))
{'price__avg': 136.4, 'price__max': Decimal('159.00'), 'price__min': Decimal('125.00'), 'price__count': 5}

分组查询

单表查询

annotate,返回值依旧是queryset

数据:

# 查询每个职业的平均工资
>>> Employee.objects.values("dep").annotate(Avg("salary"))
<QuerySet [{'dep': '副手', 'salary__avg': 4000.0}, {'dep': '船员', 'salary__avg': 3500.0}, {'dep': '船长', 'salary__avg': 4950.0}]>

多表分组查询

# 查询每一个出版社名字以及出版的书籍数目
>>> Publish.objects.values("pid").annotate(c=Count("book__title")).values("name", "c")
<QuerySet [{'name': '中国城市出版社', 'c': 2}, {'name': '武汉大学出版社', 'c': 2}, {'name': '北京大学出版社', 'c': 1}]>

# 查询每个作者的名字以及出版过的书籍的最高价格
>>> Author.objects.values("nid").annotate(max_p=Max("book__price")).values("name", "max_p")
<QuerySet [{'name': 'gy', 'max_p': Decimal('120.00')}, {'name': 'yq', 'max_p': Decimal('126.00')}, {'name': '糖加三勺', 'max_p': Decimal('125.00')}, {'name': '天蚕土豆', 'max_p': Decimal('125.00')}]>

# 查询每个书籍的名称以及对应的作者个数
>>> Book.objects.values("bid").annotate(author_count=Count("authors__nid")).values("title", "author_count")
<QuerySet [{'title': '坏蛋是怎样炼成的', 'author_count': 1}, {'title': '斗破苍穹', 'author_count': 1}, {'title': '斗罗大陆', 'author_count': 1}, {'title': '武动乾坤', 'author_count': 1}, {'title': '吞噬星空', 'author_count': 1}]>

猜你喜欢

转载自www.cnblogs.com/ExBurner/p/9236490.html
今日推荐