Django框架(八):Django模型系統(tǒng)③關(guān)聯(lián)對象操作及多表查詢

1.關(guān)聯(lián)表的數(shù)據(jù)操作

1.1 一對多

1.1.1 一對多正向

什么叫做正向:如果一個模型有外鍵字段河胎,通過這個模型對外鍵進行操作叫做正向闯袒。

  • 更新

通過屬性賦值增加

In [1]: from teacher.models import Students,Grade            

In [2]: s = Students.objects.first()               

In [3]: s                                                                                                                                                                                  
Out[3]: <Students: 小米>

In [4]: g = Grade.objects.create(name='django框架',num='7')               

In [5]: s.grade = g                    

In [6]: s.save()            

通過主鍵賦值增加

In [9]: s2.grade_id = g.id                                                                                                                                                                            
In [11]: s2.save()                                                                                                                                                         
In [12]: s2.grade                                                                                                                                                                          
Out[12]: <Grade: Grade object (1)>
  • 刪除

只有外鍵設(shè)置了 null=True,才可以通過賦值None來刪除關(guān)系

In [13]: s.grade = None                                         

In [14]: s.save()          
  • 查詢
In [16]: res = Students.objects.filter(grade__name='django框架')          #通過外鍵字段查詢                                                                                                                 

In [17]: print(res)                                                                                                                                                                        
<QuerySet [<Students: 小明>]>

In [18]: print(res.query)                                                                                                                                                                  
SELECT `teacher_students`.`id`, `teacher_students`.`name`, `teacher_students`.`age`, `teacher_students`.`sex`, `teacher_students`.`qq`, `teacher_students`.`phone`, `teacher_students`.`c_time`, `teacher_students`.`grade_id` FROM `teacher_students` INNER JOIN `teacher_grade` ON (`teacher_students`.`grade_id` = `teacher_grade`.`id`) WHERE `teacher_grade`.`name` = django框架

1.1.2 一對多反向

什么叫反向:一個模型如果被另一個模型外鍵關(guān)聯(lián),通過這個模型對關(guān)聯(lián)他的模型進行操作

In [1]: from teacher.models import Students,Grade                                                                                                                                          

In [2]: g = Grade.objects.get(pk=1)                                                                                                                                                        

In [3]: g                                                                                                                                                                                  
Out[3]: <Grade: django框架>

In [4]: g.students_set.all()                                                                                                                                                               
Out[4]: <QuerySet [<Students: 小明>]>

In [5]: Grade.students_set    #students_set為默認創(chuàng)建的反向模型管理器游岳,本質(zhì)與objects管理器沒有區(qū)別政敢,objects中有的方法,這里也有                                                         
Out[5]: <django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor at 0x7f2c0bd28908>

反向模型管理器另外起名

 grade = models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True,
                             related_name='students')  #related_name可以對反向模型管理器另外起名
  • 增加

add方法

In [7]: s = Students.objects.first()                                                                                                                                                       

In [8]: s.grade                                                                                                                                                                            

In [9]: g.students_set.add(s)   # 通過add方法胚迫,將學生增加到班級喷户,可以添加多個                                                 

In [10]: s.grade                                                                                                                                                                           
Out[10]: <Grade: django框架>

create()方法

In [11]: s1 = g.students_set.create(name='心如')    #通過create創(chuàng)建學生時添加到班級                                                                                        

In [12]: g.students_set.all()                                                                                                                                                              
Out[12]: <QuerySet [<Students: 小米>, <Students: 小明>, <Students: 心如>]>
  • 刪除

只刪除表與表之間的關(guān)系

remove()方法

In [27]: g.students_set.remove(s)                                                                                                                                                          

In [28]: g.students_set.all()                                                                                                                                                              
Out[28]: <QuerySet [<Students: 小明>, <Students: 心如>]>

clear()方法 清空
兩個方法都是直接操作數(shù)據(jù)庫,不用save保存

就是替換對象集
set()方法

1.2 多對多

如果因為有額外字段访锻,自定義了中間模型褪尝,我們需要中間模型的管理器,進行manytomany關(guān)系的創(chuàng)建和刪除期犬。
默認情況跟一對多中的 add create remove clear 用法一致
唯一區(qū)別是河哑,多對多正向的時候,多對多字段就是一個管理器龟虎,反向的時候璃谨,跟一對多的方向一致,也是在模型小寫后面加上 _set

1.3 一對一

In [1]: from teacher.models import Course,Enroll                                                                                                                                           

In [2]: c1 = Course.objects.create(name='python全棧')                                                                                                                                      

In [3]: from teacher.models import Students,StudentsDetail                                                                                                                                 

In [4]: s1 = Students.objects.first()                                                                                                                                                      

In [5]: sd1 = StudentsDetail()                                                                                                                                                             

In [6]: sd1.student = s1                

In [11]: s1.studentsdetail         #反向查詢                                                                                                                                                        
Out[11]: <StudentsDetail: 學生詳情ID1>

In [12]: sd1.student                #正向查詢                                                                                                                                                       
Out[12]: <Students: 小米>

注意遣总,如果一個被一對一管理的模型睬罗,他的實例如果沒有被分配關(guān)系,如:學生對象沒有分配學生詳情對象旭斥,如果去取容达,會拋出異常。

2.跨表查詢

例如:男生都報名了什么課程

In [31]: Course.objects.filter(student__sex=1) .distinct()  #distinct去重                                                                           
Out[31]: <QuerySet [<Course: python全棧>]>

要跨越關(guān)系垂券,只需要使用跨越模型的相關(guān)字段的字段名花盐,以下劃線分割,直到達到你想要的字段為止菇爪。

查詢所有報名包含python字母的課程的學生

In [33]: Students.objects.filter(course__name__contains='python')                                                           
Out[33]: <QuerySet [<Students: 小米>]>

例如:查詢所有報名了python全棧課程算芯,在django框架第7期班級的學員

res = Student.objects.filter(course__name='python全棧', grade__name='django框架', grade__num='7') 

例如:學員報名了python課程的班級有哪些

res = Grade.objects.filter(students__course__name__contains='python').distinct()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市凳宙,隨后出現(xiàn)的幾起案子熙揍,更是在濱河造成了極大的恐慌,老刑警劉巖氏涩,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件届囚,死亡現(xiàn)場離奇詭異,居然都是意外死亡是尖,警方通過查閱死者的電腦和手機意系,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饺汹,“玉大人蛔添,你說我怎么就攤上這事《荡牵” “怎么了迎瞧?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弦疮。 經(jīng)常有香客問我夹攒,道長,這世上最難降的妖魔是什么胁塞? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任咏尝,我火速辦了婚禮,結(jié)果婚禮上啸罢,老公的妹妹穿的比我還像新娘编检。我一直安慰自己,他們只是感情好扰才,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布允懂。 她就那樣靜靜地躺著,像睡著了一般衩匣。 火紅的嫁衣襯著肌膚如雪蕾总。 梳的紋絲不亂的頭發(fā)上粥航,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音生百,去河邊找鬼递雀。 笑死,一個胖子當著我的面吹牛蚀浆,可吹牛的內(nèi)容都是我干的缀程。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼市俊,長吁一口氣:“原來是場噩夢啊……” “哼杨凑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起摆昧,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤撩满,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后据忘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹦牛,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年勇吊,在試婚紗的時候發(fā)現(xiàn)自己被綠了曼追。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡汉规,死狀恐怖礼殊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情针史,我是刑警寧澤晶伦,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站啄枕,受9級特大地震影響婚陪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜频祝,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一泌参、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧常空,春花似錦沽一、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春蝗蛙,著一層夾襖步出監(jiān)牢的瞬間蝇庭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工捡硅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遗契,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓病曾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親漾根。 傳聞我的和親對象是個殘疾皇子泰涂,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容