1. 程式人生 > >django-多表操作

django-多表操作

#######多表操作########

多表操作和單表其實差不多,都是對資料庫的增刪查改

1、在models建立表就不多寫了,就寫寫三種關係,
    一對一:OneToOneField(),括號還有引數,其實它就是ForeignKey(unique=True),外來鍵不唯一
    一對多:ForeignKey(),外來鍵
    ## 上面著兩種你在資料庫建立表的時候,會在對應的欄位下加_id
    多對多:ManyToManyField,建立表的時候,自動會建立第三張表。

2、多表操作的增刪改,查單獨拿出來寫。
    呃呃,那我把表都寫出來吧,萬一不寫表,都不知道在寫什麼。

class Publish(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) address = models.CharField(max_length=64) email = models.EmailField() class Authorinfo(models.Model): phone = models.IntegerField() email = models.EmailField() address
= models.CharField(max_length=64) class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) sex = models.IntegerField() # 1男 2女 3其他 authorinfo = models.OneToOneField(to='Authorinfo') # 作者表和作者詳情表一對一 class Book(models.Model): id
= models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) create_time = models.DateField() publish = models.ForeignKey(to='Publish') # 和出版社一對多關係 author = models.ManyToManyField(to='Author') # 和作者多對多關係 先寫一對一的增刪改: 上面建立的表中,就Author和Authorinfo是一對一關係 首先我們必須先要有Authorinfo,這樣才能寫Author它的記錄,對吧! ret = models.Authorinfo.objects.create(phone=1787878,[email protected],address='重慶') 第一種方法: zhuyu = models.Author.objects.create(name='朱宇',sex=1,authorinfo=ret) 第二種方法: zhanghao = models.Author.objects.create(name='張昊',sex=1,authorinfo_id=2) 上面的兩種方法唯一不一樣的就是authorinfo和authorinfo_id, authorinfo = Authorinfo物件 authorinfo_id = Authorinfo物件的id authorinfo_id你在建立表之後,因為一對一關係嘛,它自動加了_id在後面,這樣寫你就直接將Authorinfo物件的id寫上 刪除修改就不寫了,和單表的一樣 models.Authorinfo.objects.filter(address='重慶').delete() # 你執行上面這行程式碼後,你的Authorinfo對應的記錄會刪除,還有就是Author中authorin_id相對應的也會刪除。 繼續寫一對多的增刪改 上面建立的表中,Publish和Book是一對多的關係,首先我手動建立幾條Publish表的記錄,先不管Book表下面的author 增: publish = models.Publish.objects.filter(pk=1).first() models.Book.objects.create(name='紅樓夢',price='33.50',create_time='2017-11-11',publish=publish) models.Book.objects.create(name='西遊記',price='59.50',create_time='2017-11-02',publish_id=2) # 對了,你通過例項的方法也行,再呼叫save方法 刪除,修改: models.Book.objects.filter(name='紅樓夢').delete() models.Book.objects.filter(name='紅樓夢').update(publish_id=2) 寫多對多的增刪改 上面建立的表中,Book和Author是多對多的關係。 # 新增 # 紅樓夢這本書新增兩位作為,叫朱宇(id=4),張昊(id=5) zhuyu = models.Author.objects.filter(name='朱宇').first() zhanghao = models.Author.objects.filter(name='張昊').first() models.Book.objects.filter(name='紅樓夢').first().author.add(zhuyu,zhanghao) # 方式一 models.Book.objects.filter(name='紅樓夢').first().author.add(4,5) # 方式二 # add方法,可以傳多個引數,可以是物件,也可以是id值 # 首先找到紅樓夢這本書,這書下面不是有author物件嘛?再呼叫add方法,傳參就好了。 # id為4,5,我是直接再資料庫看到的,只是為了方便 # 刪除 # 刪除紅樓夢這本書的兩名作者,叫張昊(id=5),朱宇(id=4) zhuyu = models.Author.objects.filter(name='朱宇').first() zhanghao = models.Author.objects.filter(name='張昊').first() models.Book.objects.filter(name='紅樓夢').first().author.remove(zhanghao,zhuyu) # 方式一 models.Book.objects.filter(name='紅樓夢').first().author.remove(4,5) # 方式二 # 清空 # 刪除完紅樓夢這本書的作者 models.Book.objects.filter(name='紅樓夢').first().author.clear() # 修改 修改無非就新增新的作者,新增也分情況,1、在原有基礎上新增(add方法可以實現),2、在空的情況下新增(set方法) # 紅樓夢這本書的作者只設置為朱宇,張昊兩個人 # 分析一下,只設置為這兩個人,萬一之前這書有其他作者,你用add方法完全不行,那就先clear,然後add再新增 models.Book.objects.filter(name='紅樓夢').first().author.clear() models.Book.objects.filter(name='紅樓夢').first().author.add(4,5) # 這樣寫是不是太麻煩了,直接用set方法就好,執行步驟差不多一致吧(猜測) models.Book.objects.filter(name='紅樓夢').first().author.set([4,5]) # set()裡面引數必須是可迭代的,你直接記傳列表就好了 下面就主要寫查了。 再寫查之前,我先寫寫正向,反向的概念,以下面這兩個表為例哈 class Authorinfo(models.Model): phone = models.IntegerField() email = models.EmailField() address = models.CharField(max_length=64) class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) sex = models.IntegerField() # 1男 2女 3其他 authorinfo = models.OneToOneField(to='Authorinfo') 通過(Author表)朱宇的作者物件,想要查詢(Authorinfo表)他的電話(phone) ---->這就是正向查詢 通過Authorinfo表)電話(phone)為18716754,查詢(Author表)哪位作者 ---->這就是反向查詢 疑問:你說憑什麼通過Author表,查到到Authorinfo表 就是正向查詢呢? 解答:因為Author表關聯一對一關係的欄位就在Author表裡,沒有為什麼。 結論:關聯表之間關係的欄位在哪個表中,那麼從那個表查詢到被關聯表的欄位,就是正向查詢,反過來就是反向查詢 好了,繼續寫一對一的查詢 正向:直接查詢欄位 反向:查詢表名的小寫 # 查詢作者叫朱宇的手機號碼(phone) 這是正向對吧 zhuyu = models.Author.objects.filter(name='朱宇').first() phone = zhuyu.authorinfo.phone # 查詢電話號碼為2147483647的作者名字 反向 phone = models.Authorinfo.objects.filter(phone=2147483647).first() name = phone.author.name ### 記住上面正向按照什麼查詢,反向又按照什麼查詢 一對多的檢視 正向:按照欄位查詢 反向:按照表名小寫_set.all(),all()只是把所有資料取了出來,是一個queryset物件 # 一對多關係就只有publish和book, # 查詢紅樓夢這本書出版社的名字 book--->publish 關聯關係欄位在book表中,所以正向吧! book = models.Book.objects.filter(name='紅樓夢').first() name = book.publish.name # 查詢重慶大學出版社出版所有書籍名字 publish--->book 反向吧 publish = models.Publish.objects.filter(name='重慶大學出版社').first() book_name = publish.book_set.all().values('name') 多對多查詢 正向:按照欄位查詢 反向:按照表名小寫_set.all(),all()只是把所有資料取了出來,是一個queryset物件 # 多對多的關係就是author和book表了 # 查詢紅樓夢這本書作者的名字 book = models.Book.objects.filter(name='紅樓夢').first() authors = book.author.all().values('name') # 查詢作者朱宇,出版的書籍名字 zhuyu = models.Author.objects.get(name='朱宇') books = zhuyu.book_set.all().values('name') # 上面這些其實是基於物件跨表查詢,子查詢,就是說拿著上一條命令的結果,執行下一條 # 完成一個指定的要求,執行了幾條sql語句 既然有基於物件跨表查詢,那麼就有不基於物件的跨表查詢,就是基於雙下劃線跨表查詢 一對一:(author,authorinfo表) # 查詢作者名字叫朱宇的手機號 方式一:phone = models.Author.objects.filter(name='朱宇').values('authorinfo__phone') 方式二:phone = models.Authorinfo.objects.filter(author__name='朱宇').values('phone') # 為什麼這麼寫? # 首先看題目,作者名字為朱宇,篩選條件已經告訴你了,所有filter肯定是朱宇 # models.Author.objects.filter(),寫在這裡的時候,你再想,我以Author為基表,找Authorinfo裡的欄位 # 作者名字是不是在基表裡?對在,那就直接filter(name='朱宇'),我想要找到Authorinfo裡的phone欄位, # 跨表查詢就用表名__欄位名就行。 # 那我們再看看方式二,一樣的思考方式,基表是誰?對就是Authorinfo,那作者名字那欄位是不是不在基表裡,跨表查詢 # 就用表名__欄位名,所有filter(author__name='朱宇'),phone在基表裡吧,直接values('phone')。 # 其實你瞭解到了這個方法,一對多,多對多都是一樣。 一對多:(publish、book表) # 查詢紅樓夢這本書的出版社的名字 方式一:name = models.Publish.objects.filter(book__name='紅樓夢').values('name') 方式二:name = models.Book.objects.filter(name='紅樓夢').values('publish__name') 多對多:(book,author表) # 查詢紅樓夢這本書的作者名字 name = models.Book.objects.filter(name='紅樓夢').values('author__name') name = models.Author.objects.filter(book__name='紅樓夢').values('name')