多表操作

多表操作

多表操作

 --

models下創建模型

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    # 閱讀數
    # reat_num=models.IntegerField(default=0)
    # 評論數
    # commit_num=models.IntegerField(default=0)

    publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
    authors=models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()
models.py

1.增刪改

在Python腳本中直接運行sql

正向:關聯關係在當前表中,從當前表去另一個表;正向查詢按字段名
反向:關聯關係不在當前表,從當前表去另一個表;反向查詢按表名小寫

一對一:

--

一對一增加(create)

authordetail=models.AuthorDatail.objects.create(addr='南京')
# author=models.Author.objects.create(name='恩公',age=17,author_detail=authordetail)
author=models.Author.objects.create(name='小猴',age=16,author_detail_id=authordetail.pk)

一對多:

 --

一對多增加(2種create)

# publish:可以傳一個publish對象
publish=models.Publish.objects.get(pk=1)
print(publish.name)
ret=models.Book.objects.create(name='西遊記',price=88,publish_date='2018-09-12',publish=publish)
# publish_id:傳一個id ret=models.Book.objects.create(name='三國演義',price=32,publish_date='2018-07-12',publish_id=publish.pk) print(type(ret.publish))

一對多修改(3種save,update)

book=models.Book.objects.get(pk=2)
book.publish_id=2
# book.publish=出版社對象
book.save()
ret=models.Book.objects.filter(pk=2).update(publish=publish對象)
ret=models.Book.objects.filter(pk=2).update(publish_id=2)

多對多:

 --

多對多增加(add)

#給紅樓夢這本書添加兩個作者(lqz,egon)
book = models.Book.objects.get(pk=1)
#相當於拿到了第三張表
往第三章表中添加紀錄(問題來了?要傳對象還是傳id),都支持
book.authors.add(1,2)

lqz = models.Author.objects.get(pk=1)
egon = models.Author.objects.get(pk=2)
book.authors.add(lqz,egon)
book.authors.add(*[lqz,egon])

 多對多刪除(remove)

#remove字段authors的id和名字都可以(名字爲通過id獲取的)
book.authors.remove(2)
book.authors.remove(egon,lqz)
book.authors.remove(1,2)
book.authors.remove(*[1,2])
book.authors.remove(*[lqz,egon])

多對多修改(set)

#修改紅樓夢這本書的作者爲lqz和egon
#先清空(清空這本的所有作者記錄)
book.authors.clear()
book.authors.add(1,2)

book.authors.set(*[6,])   #這樣不行
book.authors.set([6,])   #需要這樣傳
lqz=models.Author.objects.get(pk=2)
set 必須傳一個可迭代對象
book.authors.set([lqz,])   #需要這樣傳

(二):多表查詢(基於對象,雙下劃線)

基於對象的跨表查詢(多次查詢)
    一對一:
        -正向查詢按字段
        -反向查詢按表名小寫
    一對多:
        -正向查詢按字段(正向查詢一定會查出一個來)
        -反向查詢按表名小寫_set.all()(返回結果是queryset對象)
    
    多對多:
        -正向查詢按字段.all()(正向查詢一定會查出多個來)
        -反向查詢按表名小寫_set.all()(返回結果是queryset對象)
    
基於雙下劃線的跨表查詢
    -在filter和values中都可以做連表操作(也就是都可以寫 __)
    -正向查詢按字段
    -反向查詢按表名小寫
    
    無論以誰做基表,沒有效率之分

基於對象跨表查詢

正向查詢按字段,反向查詢:表名小寫_set

 

  • 一對一

#查詢lqz作者的地址(正向查詢,按字段)
lqz=models.Author.objects.filter(name='lqz').first()
# 作者詳情對象
print(lqz.author_detail.addr)

#查詢地址爲上海的,作者的名字(反向查詢,按表名小寫)
authordetail=models.AuthorDatail.objects.filter(addr='上海').first()
#拿到的是作者對象authordetail.author
print(authordetail.author.name)
  • 一對多

#查詢紅樓夢這本書的出版社名字(正向,按字段)
book=models.Book.objects.get(pk=1)
#出版社對象 book.publish
print(book.publish.name)
#查詢北京出版社出版的所有書名(反向查詢按 表名小寫_set.all())
publish=models.Publish.objects.get(pk=1)
#結果是queryset對象
books=publish.book_set.all()
for book in books:
    print(book.name)
#查詢以紅開頭的
books=publish.book_set.all().filter(name__startswith='紅')
for book in books:
    print(book.name)
  • 多對多

#紅樓夢這本書所有的作者(正向 字段)
book=models.Book.objects.get(pk=1)
# book.authors.all()拿到所有的作者,是一個queryset對象
authors=book.authors.all()
for author in authors:
    print(author.name)
#查詢egon寫的所有書(反向 表名小寫_set.all())
egon=models.Author.objects.get(pk=2)
#拿到的是queryset對象
books=egon.book_set.all()
for book in books:
print(book.name)

基於雙下滑線跨表查詢

正向查詢按字段,反向查詢:表名小寫__字段名

 

  • 一對一

#查詢lqz作者的名字,地址(正向查詢,按字段)
ret=models.Author.objects.filter(name='lqz').values('name','author_detail__addr')
print(ret)
#查詢地址爲上海的作者的名字(反向,按表名小寫)
ret=models.AuthorDatail.objects.filter(addr='上海').values('addr','author__name','author__age')
print(ret.query)
print(ret)
  • 一對多

#查詢紅樓夢這本書的出版社的名字(正向  按字段)
ret=models.Book.objects.filter(name='紅樓夢').values('name','publish__name')
print(ret)
#查詢北京出版社出版的所有書的名字(反向  按表名小寫)
ret=models.Publish.objects.filter(name='北京出版社').values('book__name')
print(ret)
  • 多對多

#紅樓夢這本書所有的作者名字(正向  按字段)
ret=models.Author.objects.filter(book__name='紅樓夢').values('name')
print(ret)

ret=models.Book.objects.filter(name='紅樓夢').values('authors__name')
print(ret)
#egon出版的所有書的名字(反向 表名小寫)
ret=models.Book.objects.filter(authors__name='egon').values('name')
print(ret)
ret=models.Author.objects.filter(name='egon').values('book__name')
print(ret)
#查詢北京出版社出版過的所有書籍的名字以及作者的姓名
ret=models.Publish.objects.filter(name='北京出版社').values('book__name','book__authors__name')
print(ret)
ret=models.Book.objects.filter(publish__name='北京出版社').values('name','authors__name')
print(ret)
ret=models.Author.objects.filter(book__publish__name='北京出版社').values('book__name','name')
print(ret)
#地址是以北開頭的作者出版過的所有書籍名稱以及出版社名稱
#以authordetial爲基表 ret = models.AuthorDatail.objects.filter(addr__startswith='北').values('author__book__name', 'author__book__publish__name') print(ret) #以book爲基表 ret=models.Book.objects.filter(authors__author_detail__addr__startswith='北').values('name','publish__name') print(ret.query)
#以author爲基表 ret=models.Author.objects.filter(author_detail__addr__startswith='北').values('book__name','book__publish__name') print(ret.query)
posted @ 2019-03-02 16:09 ChuckXue 閱讀(...) 評論(...) 編輯 收藏
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章