15.Django(多表的增、删、改、查)

多表的增

  • 一对一

    作者表与作者详细信息表是一对一的关系。由于作者表收信息表的限制,所以我们给信息表增加一条记录,再给作者表增加一条记录。

    • 方法一:类的属性对应对应

          detail_obj = models.AuthorDetail.objects.create(
            birthday='1999-04-02',
            telephone='16632279999',
            addr='河北保定',
        )
      ​
        models.Author.objects.create(
            name='牧羊小董',
            age=21,
            AuthorDetail=detail_obj,
        )
    • 方法二:表的字段名对应对想的id(推荐)

          detail_obj = models.AuthorDetail.objects.create(
            birthday='1999-04-02',
            telephone='16632279999',
            addr='河北保定',
        )
      ​
        models.Author.objects.create(
            name='牧羊小董',
            age=21,
            AuthorDetail_id=detail_obj.id,
        )
  • 多对一

    Book表与Publish表是多对一的表

    • 方式一:类的属性对应对象

          book_obj = models.Book.objects.create(
            title='大朗的美好生活',
            publishDate='1721-12-20',
            price=29.55,
            Publish=models.Publish.objects.get(id=3),
        )
    • 方式二:表的字段名字对应对象的id(推荐)

          book_obj = models.Book.objects.create(
            title='大朗的美好生活',
            publishDate='1721-12-20',
            price=29.55,
            Publish_id=3,
        )

      总结:

      一对一的外键字段设置在哪张表,这张表就是关联表,另一张表就叫做被关联表,删除被关联表的记录,关联表的记录会联级删除,反之则不会。

  • 多对多

    Book表与Author表,我们不需要对Book或者Author增加记录了,我们只需要给第三张表增加Book表与Author表的对应关系即可。

    如何找到第三张表?

    由于第三张表是orm通过Book表中Atuhot(多对多字段)自动生成的,所以我们要接触与Author这个字段找到第三张表。

    • 方式一:常用方式

      给《大朗的美好生活》这本书,添加两个个作者

      book_obj = models.Book.objects.get(id=4)
      book_obj.Author.add(4, 5)  # 这里的Author不是表名,是多对多字段名
      # 或者另一种写法
      book_obj,Author.add(*[4,5])
    • 方式二:

      author1 = models.Author.objects.get(id=1)
      author2 = models.Author.objects.get(id=3)
      ​
      book_obj = models.Book.objects.get(id=4)
      book_obj.Author.add(author1, author2) # 这里的Author不是表名,是多对多字段名
      # 另一种写法
      book_obj.Author.add(*[author1, author2])

       

多表的删除

  • 一对一

    一对一的删除与单表的删除没有区别

    # 删除作者表的一条记录,对应信息表的记录不会联级删除
    models.Author.objects.get(id=1).delete()
    ​
    # 删除信息表的一条记录,对应的作者表的记录会联级删除
    models.AuthorDetail.ovjects.get(id=5).delete()
  • 多对一

    多对一 与 一对一 的删除一样的。 Book表与Publish表

    # 删除Book表的一条记录,对应Publish表的记录不会联级删除
    models.Book.objects.get(id=4).delete()
    ​
    # 删除Publish表的一条记录,对应的Book表中的记录会联级删除
    models.Publish.objects.get(id=3).delete()

    总结:

    多对的外键字段设置在哪张表,这张表就是关联表,另一张表就叫做被关联表,删除被关联表的记录,关联表的记录会联级删除,反之则不会。

  • 多对多

    Author表与Book表是多对多的表,删除并不是删除这两张表的记录,而是删除第三张表的对应关系,我们还是需要通过Book类中的Author属性找到第三张表

    • remove方法

      # 删除一个作者
      book_obj = models.Book.objects.get(id=6) # 获取到书籍
      book_obj.Author.remove(4)  # 删除对应书籍的 id为4的作者
      ​
      # 删除两个作者
      book_obj = models.Book.objects.get(id=6)
      book_obj.Author.remove(*[3,4])
    • clear方法

      book_obj = models.Book.objects.get(id=6)
      book_obj.Author.clear()   # 直接情况所有作者

 

多表的改

  • 一对一

    一对一与多对一的改与单表的操作一样的

    • 方式一:类的属性对应对象

      models.Author.objects.filter(id=3).update(
      age=24,
      AuthorDetail=models.AuthorDetail.objects.get(id=7),
      )
    • 方式二:表的字段名对应对象的id(推荐)

      models.Author.objects.filter(id=3).update(
      age=24,
      AuthorDetail_id=7,
      )
  • 多对一

    Book表与Publish表

    • 方式一:类的属性对应对象

      models.Book.objects.filter(id=6).update(
      title='三毛学IT',
      Publish=models.Publish.objects.get(id=2),
      )
    • 方式二:表的字段名对应对象的id(推荐)

      models.Book.objects.filter(id=1).update(
      Publish_id=4
      )
    • 细节(万能属性PK)。坑

  • 多对多

    Author表与Book表

    需求:将Book表中id为8的这本书的作者改成作者id为2、4的。

    • 方法一: 可以先清空,在添加。

    • 方法二:set

      book_obj = models.Book.objects.get(id=8)
      # set使用必须是字符串形式
      # book_obj.author.set('2')
      book_obj.author.set(['2','4'])

       

多表的查询

正向查询:

建立关系的属性在哪张表。从这张彪查询另一张表的信息,就叫正向查询
​
也就是说:从关联表查询被关联表中的信息就是正向查询

反向查询:

反向查询:从另一张表查询有建立关系的属性的表中的信息,就叫做反向查询
​
也就是说:从被关联表查询关联表中的信息就是反向查询

 

基于对象的跨表查询

基于对象的跨表查询本质上就是我们之前讲的子查询(一个SQL语句的查询结果作为另一个查询条件)

  • 一对一

    Author表 和 AuthorDetail表 是一对一的关系。

    • 正向查询:

      需求:找到指定姓名的详细信息

      通过对象.关联字段的属性    ————> 获取到另一个表的对象
      ​
      author_obj = models.Author.objects.get(name='指定的名字')
      print(author_obj.AuthorDetail)  # 这是详细记录表的一个对象
      print(auhtor_obj.AuthoDetail.id)
      print(auhtor_obj.AuthoDetail.birthday)
      print(auhtor_obj.AuthoDetail.telephone)
    • 反向查询

      需求:通过电话号码,找到此人的姓名、年龄

      通过对象.小写类名   ——————————> 获取到另一个表的对象
      ​
      authordetail_obj = models.AuthorDetail.objects.get(telephone='电话号码')
      print(authordetail_obj.author) # 返回的是对应的对象
      print(authordetail_obj.author.name)
      print(authordetail_obj.author.age)
    •  

       

  • 多对一

    Book表 和 Publish表 是多对一的关系

    • 正向查询

      需求:通过制定书籍名称,找到这本书的出版社

      book_obj = models.Book.objects.get(title='指定的书籍名称')
      print(book_obj.Publish.name)
    • 反向查询

      需求:查询指定出版社 出版的所有书籍

      publish_obj = models.Publish.objects.get(name="指定出版社的名字")
      print(publish_obj.book_set) # 类似于objects控制器也就是models对象。通过这个对象可以调用get、filter、all等等查询方法
      print(publish_obj.book_set.all())
      print(publish_obj.book_set.first())
      print(publish_obj.book_set.filter(title='xxx')
    •  

       

  • 多对多

    Book表 和 Author表 是多对多的关系

    • 正向查询

      需求:查询指定书的id是由哪个作者写的

      book_obj = models.Book.objects.get(id=指定的id)
      print( book_obj.Author.all())
    • 反向查询

      需求:查询指定作这写了哪些书

      author_obj = models.Author.objects.get(name='指定作者名字')
      print(authoe_obj.Book_set.all())
      print(authoe_obj.Book_set.first())

  • 总结

    对于基于对象的跨表查询
    正向查询:无论是一对一 还是多对一 还是多对多都是 对象.属性
    反向查询:一对一是通过对象.小写类名 而多对一以及多对多都是对象.小写类型_set

     

基于双下划线的跨表查询

类似于MySQL里面的连表操作

MySQL的连表操作:
笛卡尔积
inner join 内连接
left join 左连接
right join 右连接
全连接
  • 一对一

    Author表 和 AuthorDetail表 是一对一的关系

    • 正向查询

      需求:查询指定姓名的电话号码

      AuthoeDetail__ 这个语句做了一个连表操作,Author表与AuthorDetail表的连接操作。

      author_obj = models.Author.objects.filter(name='指定姓名').values(
      'AuthorDetail__name'
      )
      print(author_obj)
    • 反向查询 需求1:查询指定姓名的电话号码

      obj = models.AuthorDetail.objects.filter(name='指定姓名').values(
      'author__name',
      'author__age',
      'addr',
      )
      print(obj)

      需求2:查询指定电话号码的用户的姓名

      obj = models.AuthorDeatail.objects.filter(telephone='指定电话号码').values(
      'author__name',
      'authoe__age',
      'addr'
      )
      print(obj)
  • 多对一

    Book表 和 Publish表 是多对一的关系

    • 正向查询

      需求:查询 指定书籍的 的出版社

      obj = models.Book.objects.filter(title='指定书籍名').values(
      'Publish_name'
      )
      print(obj)
    • 反向查询

      需求:查询 指定书籍的 的出版社

      obj = models.Publish.objects.filter(book__title='指定书籍名').values(
      'name',
      'book__price',
      )
      print(obj)
      print(obj[0].get('book_price'))
      print(obj[0]['book_price'])
  • 多对多

    Book表以及Author表

    • 正向查询

      需求:查询 指定书籍的作者们

      obj = models.Book.objects.filter(title='指定书籍').values(
      'author__name',
      )
      print(obj)
    • 反向查询

      需求:查询 指定书籍的作者们

      obj = models.Author.objects.filter(book__title='指定书籍').values(
      'name',
      'age',
      )
      print(obj)
    •  

posted @ 2020-06-04 15:42  牧羊小董  阅读(273)  评论(0)    收藏  举报