Day50 python 多表操作

 

2.一对多

#  一对多新增
    # 方式一 传对象的形式
    pub_obj = models.Publish.objects.get(pk=1)
    # book = models.Book.objects.create(title="独孤九剑", price=140, pub_date="2008-08-23", publish=pub_obj)
    # 方式二 传对象id(用的更多)
    # book = models.Book.objects.create(title="冲灵剑法", price=140, pub_date="2018-08-23", publish_id=pub_obj.pk)

    print(book)#Book object (1) Book object (2)

 

 3、多对多

方式1:

# 多对多的新增
    # 方式1 传对象的形式

    # book_obj = models.Book.objects.get(pk=1)
    # ling = models.Author.objects.get(pk=2)
    # ying = models.Author.objects.get(pk=3)
    # book_obj.authors.add(ling, ying)

方式2

# 插入对象的id
# 方式2 传对象的id
book_obj = models.Book.objects.get(pk=2)
ling = models.Author.objects.get(pk=2)
book_obj.authors.add(ling.pk)
 

注意:

不能使用关联管理器中的add方法就行使用:只能用在一对多的多的上面才行。(多对多也行)

 # book_obj.publish.add(ling) 如果想在这个是多对一1,不能使用add关联其他的对象

2.关联管理器

2.1add方法

大前提:

- 多对多,双向都有

- 一对多时,对应多的一方才有(出版社的角度),给1对多的1添加字段等于

  一对多时,反向才能使用关联管理器

 

2.2 create方法(可以正向添加或者反向添加)

创建一个新的对象,保存对象,并将它添加到关联对象集之中。返回新创建的对象:

>>> author_obj = Author.objects.get(id=1)
>>> book = author_obj.book_set.create(
    ...
    title='挤奶龙爪手',
    ...
)

# No need to call e.save() at this point -- it's already been saved.
这完全等价于(不过更加简洁于):

>>> author_obj = Author.objects.get(id=1)
>>> book = Book(
    ...
    title='挤奶龙爪手',
    ...
)
>>> author_obj.save(force_insert=True)
要注意我们并不需要指定模型中用于定义关系的关键词参数。在上面的例子中,我们并没有传入author_obj参数给create()。Django会明白新的 Book对象author_obj 应该添加到author_obj中。

 

小结:

正向按字段名
方向按小写表名+  _set

 

 例:

# create方法
    ling = models.Author.objects.get(pk=2)
    ling.book_set.create(title="吸星大法", price=110, pub_date="2011-12-12", publish_id=1)
# 将数据加入app01_book中 并把它添加到关联的对象集中去。创建了2张表中的数据

创建上面的第三条数据。,

关系表中也创建了第4条数据。

4、基于对象的跨表查询

 1、一对多查询(Publish 与 Book)

 

##### 基于对象的跨表查询####
    # 一对多的关系:
    # 查询主键为1的书籍的出版社所在的城市
    # 1.正向
    book_obj = models.Book.objects.filter(pk=1).first()
    print(book_obj.publish.city)
#华山
    # 2.反向
    # 查询华山出版社的出版的书籍名
    # 分析先先查询华山的和book表关联的字段是id,于是先查出关联的字段 然后就行反查
  # publish表中和app01_book表中关联的字段就是publish的id
pub_obj = models.Publish.objects.filter(name="华山出版社").first() for book in pub_obj.book_set.all(): print(book.title) return HttpResponse("查询成功!")


#独孤九剑
#冲灵剑法
#吸星大法

在创建类的时候,写的是关联的publish这个对象类,其实只是在内部关联的一个类默认创建的publish_id作为关联字段,即是传入的时候可以是对象和publish_id 

 
 

 4.2.一对一查询(Author 和 AuthorDetail)


#
反向时 直接小写的表名即可 不用_set # 查询林狐冲的电话 # 查询出林狐冲对象
# 正向查询 author_obj = models.Author.objects.filter(name="林狐冲").first() print(author_obj.au_detail.tel) 分析:电话在下一张的表中,于是我们把和下一张细节表相关的字段查出来。感觉就是自己找到相关联的字段就行跳到下一张表就行了!

反向查询(按表名:author):
# 查询所有住址在黑木崖的作者和姓名    au_detail_obj 对象也就是记录不知一条记录满足条件的!au在黑木崖的对象的单条()这里用了反向但是没有使用_set
    au_detail_obj = models.AuthorDetail.objects.filter(addr="黑木崖")
    for au in au_detail_obj:
        print(au.author.name)
# 任我行
# 任盈盈

 4.3、多对多查询 (Author 与 Book)

# 正向
    # 独孤九剑度所有作者的名字以及手机号
    # 分析 独孤九剑是书名肯定是在book表当中的,先把满足条件的记录即是对象的集合先拿出来
    book_obj = models.Book.objects.filter(title="独孤九剑").first()
    # 写独孤九剑的作者不只一个
    for au in book_obj.authors.all():
        print(au.name, au.au_detail.tel)
        # 任我行 13943454554
        # 任盈盈 13878934322

 

分析:书表和作者表通过,authors字段就行关联,作者表和作者详细信息表之间通过au_detail字段就行关联,直接一直找去下就完事! 

 

5.基于双下划线的跨表查询(****) 

# 一对多关系:
    # 练习:  查询华山出版社出版过的所有书籍的名字与价格(一对多)(publish__name已经跨表了)
#
分析:查询的是华山出版社的书籍名字和价格,需要的是名字和价格在book表中,出版社的字样是在publish的表中
第一种:从book表开始往下面查即是正向查询,直接在过滤的时候使用publish_name就行跳表条件就行过滤!
第二种:从publish表开始往上边查即是反向查询,

 

    # 正向:
    # book = models.Book.objects.filter(publish__name="华山出版社").values("title", "price")
运行结果:
 <QuerySet [
{'title': '独孤九剑', 'price': Decimal('140.00')},
{'title': '冲灵剑法', 'price': Decimal('140.00')},
{'title': '吸星大法', 'price': Decimal('110.00')}
]>

 

# 反向查询 按表名:book
    book = models.Publish.objects.filter(name="华山出版社").values("book__title", "book__price")
    print(book)

运行结果:
<QuerySet [
{'book__title': '独孤九剑', 'book__price': Decimal('140.00')},
{'book__title': '冲灵剑法', 'book__price': Decimal('140.00')},
{'book__title': '吸星大法', 'book__price': Decimal('110.00')} ]>

 

#  多对多关系:
    # 练习: 查询令狐冲出过的所有书籍的名字(多对多)
    # 正向
    # 分析:需要的是所有书籍的名字,在book表中,其次就是在作者表中去查询是令狐冲的的id是多少即是author_id
    # 正向
    book = models.Book.objects.filter(authors__name="令狐冲").values("title")
    print(book)
    # 反向
    book = models.Author.objects.filter(name="令狐冲").values("book__title")
    print(book)

<QuerySet []>
<QuerySet [{'book__title': None}]>

 

 小结:多对多之间,author和 book 、publish之间,有关联的话直接跳就行了。

 # 一对1的练习

# 查询令狐冲的手机号
    # 正向
    book = models.Author.objects.filter(name="令狐冲").values('au_detail__tel')
    print(book)
    book = models.AuthorDetail.objects.filter(author__name="令狐冲").values('tel')
    print(book)

# <QuerySet [{'au_detail__tel': '13432335433'}]>
# <QuerySet [{'tel': '13432335433'}]>

 

 # 综合练习

# 练习1: 查询华山出版社出版过的所有书籍的名字以及作者的姓名
    # 正向
    book = models.Book.objects.filter(publish__name="华山出版社").values('title', 'authors__name')
    print(book)
    # 反向
    book = models.Publish.objects.filter(name="华山出版社").values("book__title", "book__authors__name")

    print(book)
# 正向运行结果:
<QuerySet [
{'title': '独孤九剑', 'authors__name': '任我行'},
{'title': '冲灵剑法', 'authors__name': '任我行'},
{'title': '吸星大法', 'authors__name': '任我行'},
{'title': '独孤九剑', 'authors__name': '任盈盈'}]> # 反向运行结果: <QuerySet [
{'book__title': '独孤九剑', 'book__authors__name': '任我行'},
{'book__title': '冲灵剑法', 'book__authors__name': '任我行'},
{'book__title': '吸星大法', 'book__authors__name': '任我行'},
{'book__title': '独孤九剑', 'book__authors__name': '任盈盈'}]>

 

转载于:https://www.cnblogs.com/longerandergou/p/11154154.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值