Django入门开发实战

Django模型层之多表操作(四)

2019-01-07  本文已影响6人  乔治大叔

基于双下划线的跨表查询

Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止。

'''
正向查询按字段,反向查询按表名小写用来告诉ORM引擎join哪张表
'''

一对多查询

# 练习:  查询苹果出版社出版过的所有书籍的名字与价格(一对多)

    # 正向查询 按字段:publish

    queryResult=Book.objects
            .filter(publish__name="苹果出版社")
            .values_list("title","price")

    # 反向查询 按表名:book

    queryResult=Publish.objects
              .filter(name="苹果出版社")
              .values_list("book__title","book__price")
查询的本质一样,就是select from的表不一样
# 正向查询按字段,反向查询按表名小写
    # 查询红楼梦这本书出版社的名字
    # select * from app01_book inner join app01_publish
    # on app01_book.publish_id=app01_publish.nid
    ret=Book.objects.filter(name='红楼梦').values('publish__name')
    print(ret)
    ret=Publish.objects.filter(book__name='红楼梦').values('name')
    print(ret)

多对多查询

# 练习: 查询alex出过的所有书籍的名字(多对多)

    # 正向查询 按字段:authors:
    queryResult=Book.objects
            .filter(authors__name="yuan")
            .values_list("title")

    # 反向查询 按表名:book
    queryResult=Author.objects
              .filter(name="yuan")
              .values_list("book__title","book__price")
# -------多对多正向查询
    # 查询红楼梦所有的作者
    ret=Book.objects.filter(name='红楼梦').values('authors__name')
    print(ret)
    # ---多对多反向查询
    ret=Author.objects.filter(book__name='红楼梦').values('name')
    ret=Author.objects.filter(book__name='红楼梦').values('name','author_detail__addr')
    print(ret)
# 正向查询按字段,反向查询按表名小写
    # 查询红楼梦这本书出版社的名字
    # select * from app01_book inner join app01_publish
    # on app01_book.publish_id=app01_publish.nid
    ret=Book.objects.filter(name='红楼梦').values('publish__name')
    print(ret)
    ret=Publish.objects.filter(book__name='红楼梦').values('name')
    print(ret)
    # sql 语句就是from的表不一样
    # -------多对多正向查询
    # 查询红楼梦所有的作者
    ret=Book.objects.filter(name='红楼梦').values('authors__name')
    print(ret)
    # ---多对多反向查询
    ret=Author.objects.filter(book__name='红楼梦').values('name')
    ret=Author.objects.filter(book__name='红楼梦').values('name','author_detail__addr')
    print(ret)

一对一查询

# 查询alex的手机号
    
    # 正向查询
    ret=Author.objects.filter(name="alex").values("authordetail__telephone")

    # 反向查询
    ret=AuthorDetail.objects.filter(author__name="alex").values("telephone")
# 查询lqz的手机号
    # 正向查
    ret=Author.objects.filter(name='lqz').values('author_detail__telephone')
    print(ret)
    # 反向查
    ret= AuthorDatail.objects.filter(author__name='lqz').values('telephone')
    print(ret)

进阶练习(连续跨表)

# 练习: 查询人民出版社出版过的所有书籍的名字以及作者的姓名


    # 正向查询
    queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","authors__name")
    # 反向查询
    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__authors__age","book__authors__name")


# 练习: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称


    # 方式1:
    queryResult=Book.objects
            .filter(authors__authorDetail__telephone__regex="151")
            .values_list("title","publish__name")
    # 方式2:    
    ret=Author.objects
              .filter(authordetail__telephone__startswith="151")
              .values("book__title","book__publish__name")
# ----进阶练习,连续跨表
    # 查询手机号以33开头的作者出版过的书籍名称以及书籍出版社名称
    # author_datail author book publish
    # 基于authorDatail表
    ret=AuthorDatail.objects.filter(telephone__startswith='33').values('author__book__name','author__book__publish__name')
    print(ret)
    # 基于Author表
    ret=Author.objects.filter(author_detail__telephone__startswith=33).values('book__name','book__publish__name')
    print(ret)
    # 基于Book表
    ret=Book.objects.filter(authors__author_detail__telephone__startswith='33').values('name','publish__name')
    print(ret)
    # 基于Publish表
    ret=Publish.objects.filter(book__authors__author_detail__telephone__startswith='33').values('book__name','name')
    print(ret)

related_name

publish = ForeignKey(Blog, related_name='bookList')

反向查询时,如果定义了related_name ,则用related_name替换表名,例如:

# 练习: 查询人民出版社出版过的所有书籍的名字与价格(一对多)

# 反向查询 不再按表名:book,而是related_name:bookList


    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("bookList__title","bookList__price")

上一篇下一篇

猜你喜欢

热点阅读