亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于Django ORM、一對一、一對多、多對多的全面講解

 更新時(shí)間:2019年07月26日 10:19:30   作者:青春永不言棄  
今天小編就為大家分享一篇基于Django ORM、一對一、一對多、多對多的全面講解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧

上篇博客也提到這些知識點(diǎn),可能大家還是不太清楚,這篇博客為大家詳細(xì)講解ORM中的幾個(gè)知識點(diǎn)

1.1首先我們先看一個(gè)小案例:

#_*_coding:utf-8_*_
from django.db import models
 
# Create your models here.
 
class Colors(models.Model):
 colors=models.CharField(max_length=10) #藍(lán)色
 def __str__(self):
  return self.colors
 
class Ball(models.Model):
 color=models.OneToOneField("Colors") #與顏色表為一對一,顏色表為母表
 description=models.CharField(max_length=10) #描述
 def __str__(self):
  return self.description
 
class Clothes(models.Model):
 color=models.ForeignKey("Colors") #與顏色表為外鍵,顏色表為母表
 description=models.CharField(max_length=10) #描述
 def __str__(self):
  return self.description 
  
class Child(models.Model):
 name=models.CharField(max_length=10) #姓名 
 favor=models.ManyToManyField('Colors') #與顏色表為多對多
 

先來區(qū)分一下什么是一對一、多對多

一對一:子表從母表中選出一條數(shù)據(jù)一一對應(yīng),母表中選出來一條就少一條,子表不可以再選擇母表中已被選擇的那條數(shù)據(jù)

一對多:子表從母表中選出一條數(shù)據(jù)一一對應(yīng),但母表的這條數(shù)據(jù)還可以被其他子表數(shù)據(jù)選擇

共同點(diǎn)是在admin中添加數(shù)據(jù)的話,都會出現(xiàn)一個(gè)select選框,但只能單選,因?yàn)椴徽撘粚σ贿€是一對多,自己都是“一”

多對多總結(jié):

比如有多個(gè)孩子,和多種顏色、

每個(gè)孩子可以喜歡多種顏色,一種顏色可以被多個(gè)孩子喜歡,對于雙向均是可以有多個(gè)選擇

應(yīng)用場景

一對一:一般用于某張表的補(bǔ)充,比如用戶基本信息是一張表,但并非每一個(gè)用戶都需要有登錄的權(quán)限,不需要記錄用戶名和密碼,此時(shí),合理的做法就是新建一張記錄登錄信息的表,與用戶信息進(jìn)行一對一的關(guān)聯(lián),可以方便的從子表查詢母表信息或反向查詢

外鍵:有很多的應(yīng)用場景,比如每個(gè)員工歸屬于一個(gè)部門,那么就可以讓員工表的部門字段與部門表進(jìn)行一對多關(guān)聯(lián),可以查詢到一個(gè)員工歸屬于哪個(gè)部門,也可反向查出某一部門有哪些員工

多對多:如很多公司,一臺服務(wù)器可能會有多種用途,歸屬于多個(gè)產(chǎn)品線當(dāng)中,那么服務(wù)器與產(chǎn)品線之間就可以做成對多對,多對多在A表添加manytomany字段或者從B表添加,效果一致

一對一

查:

#子表查詢母表,找到紅球?qū)?yīng)的顏色
#寫法1:
print(models.Ball.objects.get(description="紅球").color.colors) #返回紅,通過子表查詢母表,寫法:"子表對象.母表表名的小寫.母表字段名" ;通過Ball表查到description為"紅球",查找到對應(yīng)colors
#寫法2,反向從母表入手:
print(models.Colors.objects.get(ball__description="紅球").colors) #返回紅,通過子表查詢母表,但形式上是從母表對象自身直接獲取字段,寫法:"母表.objects.get(子表名小寫__子表字段="xxx").母表字段名" ;效果和上邊完全一致,另一種形式


#母表查詢子表,找到紅色對應(yīng)的球的名字
#寫法1:
print(models.Colors.objects.get(colors="紅").ball.description) #返回紅球,通過母表查詢子表,寫法:"母表對象.子表表名的小寫.子表字段名";找到顏色為紅色的Ball的description
#寫法2,反向從子表入手:
print(models.Ball.objects.get(color__colors="紅").description) #返回紅球,通過母表查詢子表,但形式上是從子表對象自身直接獲取字段,寫法:"子表.objects.get(一對一的子表字段__母表字段="xxx").子表字段";效果和上邊完全一致,另一種形式

增:

#添加一種顏色黑,并添加黑球
color_obj=models.Colors.objects.create(colors="黑") #先在母表中創(chuàng)建顏色,并實(shí)例化給顏色表對象
models.Ball.objects.create(color=color_obj,description="黑球") #更新Ball表,color字段為顏色表對象,添加description字段

備注:增添數(shù)據(jù)的3種常用方式

#增添數(shù)據(jù)的三種寫法:
#寫法1:
color_obj=models.Colors.objects.create(colors="黑")
models.Ball.objects.create(color=color_obj,description="黑球")
#寫法1補(bǔ)充:
color_id=models.Colors.objects.create(colors="黑").id
models.Ball.objects.create(color_id=color_id,description="黑球")
#寫法2:
color_obj=models.Colors.objects.create(colors="黑")
ball_obj=models.Ball(color=color_obj,description="黑球")
ball_obj.save()
#寫法3(字典導(dǎo)入):
color_obj=models.Colors.objects.create(colors="黑")
ball_dic={'description':"黑球"}
models.Ball.objects.create(color=color_obj,**ball_dic)

改:

color_obj=models.Colors.objects.get(colors="黑") #.get()等同于.filter().first()
color_obj.colors="灰"
color_obj.save()
models.Ball.objects.filter(description="黑球").update(color=color_obj,description="灰球") #update(),delete()是QuerySet的方法

備注:修改數(shù)據(jù)的常見方式

#更新一條數(shù)據(jù)
color_obj=models.Colors.objects.get(colors="黑")
color_obj.colors="灰"
color_obj.save()
#更新多條數(shù)據(jù),把滿足條件的球的description都變?yōu)榛仪?
#寫法1:
models.Ball.objects.filter(color__colors="紅").update(description="灰球")
#寫法2:
up_dic={"description":"灰球"}
models.Ball.objects.filter(id__gt=0).update(**up_dic)

刪:

models.Ball.objects.get(description="灰球").delete() #對象和QuerySet都有方法delete()
models.Colors.objects.filter(colors="灰").delete()

models.Colors.objects.all().delete() #清空一張表

一對多(外鍵)

查:

#外鍵表聯(lián)合查詢:

#外鍵子表查詢母表,與一對一子表查詢母表形式一致
#找到紅褲衩所屬的顏色表中的顏色--返回:紅
#寫法1:
print(models.Clothes.objects.get(description="小虎哥").color.colors) #返回紅,通過子表查詢母表,寫法:"子表對象.母表表名的小寫.母表字段名" ;通過Clothes表查到description為"小虎哥",查找到對應(yīng)colors
#寫法2,反向從母表入手:
print(models.Colors.objects.get(clothes__description="小虎哥").colors) #返回紅,通過子表查詢母表,但形式上是從母表對象自身直接獲取字段,寫法:"母表.objects.get(子表名小寫__子表字段="xxx").母表字段名" ;效果和上邊完全一致,另一種形式

#外鍵母表查詢子表,與一對一形式不同,因?yàn)槟副頌?多",不能像一對一一樣通過.get().子表.子表字段的方式獲取,但與多對多母表查詢子表一致
#找到顏色為紅的所有服裝--返回:[<Clothes: 大美女>, <Clothes: 小虎哥>]
#寫法1:
color_obj=models.Colors.objects.get(colors="紅")
print(color_obj.clothes_set.all()) #注意:子表小寫_set的寫法,它實(shí)際上是一個(gè)QuerySet,可以用update,delete,all,filter等方法
#寫法2:
print(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="紅")))
#寫法2簡便寫法(推薦):
print(models.Clothes.objects.filter(color__colors="紅")) #寫法:filter(子表外鍵字段__母表字段='過濾條件')
#寫法3:
color_id=models.Colors.objects.get(colors="紅").id #通過母表獲取到顏色為紅的id
print(models.Clothes.objects.filter(color_id=color_id)) #filter得到QuerySet,寫法:filter(子表外鍵字段_母表主鍵=母表主鍵對象)

備注:通過QuerySet的.values()方法,將QuerySet轉(zhuǎn)化為ValuesQuerySet

print(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="紅")).values('color__colors','description')) #獲取子表的description字段,和母表的colors字段,獲取母表字段寫法: 子表外鍵字段名__母表字段名--適用于values()或filter()
#簡寫形式補(bǔ)充:
print(models.Clothes.objects.filter(color__colors="紅").values('color__colors','description'))
#返回:
[{'description': u'\u7ea2\u5185\u8863', 'color__colors': u'\u7ea2'}, {'description': u'\u7ea2\u5185\u88e4', 'color__colors': u'\u7ea2'}]
#如果不加values(),返回的是[<Clothes: 大美女>, <Clothes: 小虎哥>]這樣一個(gè)QuerySet集合,通過values可以形成一個(gè)列表,列表中的每一個(gè)元素是一個(gè)字典,可以通過list()將ValuesQeurySet轉(zhuǎn)化為列表,之后返回給templates


#另外可通過.values_list()將QuerySet轉(zhuǎn)化為ValuesListQuerySet。返回:[(u'\u7ea2', u'\u7ea2\u889c\u5b50'), (u'\u7ea2', u'\u7ea2\u889c\u5b50')]
#得到的是一個(gè)列表,列表中是多個(gè)元組,每個(gè)元組是ValuesQuerySet中字典的value,常用于從models里將數(shù)據(jù)取出后動態(tài)添加到前端模板中的select選項(xiàng)中。
#通過forms.py從models取值傳給前端select選項(xiàng),需重啟django后,select選項(xiàng)才能更新,可在定義form時(shí),添加如下關(guān)鍵字保障動態(tài)更新select選項(xiàng)
#forms.py
from django import forms
from test1 import models
class ClothesForm(forms.Form):
 color=forms.IntegerField(required=True,widget=forms.Select(),)
 def __init__(self,*args,**kwargs): #定義這個(gè)關(guān)鍵字段,當(dāng)使用form時(shí),colors表新增了顏色,前端ClothesForm的color字段的選項(xiàng)會自動更新
  super(ClothesForm, self).__init__(*args,**kwargs)
  self.fields['color'].widget.choices=models.Colors.objects.all().order_by('id').values_list('id','colors')

增:

#增添子表數(shù)據(jù),形式與一對一一致
#添加顏色為綠的服裝:小帥哥
#方法1:
models.Clothes.objects.create(color=models.Colors.objects.get(colors="綠"),description="小帥哥")
#方法1補(bǔ)充:
models.Clothes.objects.create(color_id=models.Colors.objects.get(colors="綠").id,description="小帥哥")
#方法2:
c_obj=models.Clothes(color=models.Colors.objects.get(colors="綠"),description="小帥哥")
c_obj.save()
#方法3:字典方式錄入..參考一對一

改:

#顏色為紅的服裝,description都更新為大美女
#寫法1:
models.Clothes.objects.filter(color__colors="紅").update(description="大美女")
#寫法2:
models.Clothes.objects.filter(color_id=models.Colors.objects.get(colors="紅").id).update(description="大美女")
#寫法3:
colors_obj=models.Colors.objects.get(colors="紅")
colors_obj.clothes_set.filter(id__gte=1).update(description="大美女")
#其他寫法參照一對一的修改和外鍵的查詢

刪:

models.Clothes.objects.get(description="灰裙子").delete() #對象和QuerySet都有方法delete()
models.Colors.objects.filter(colors="灰").delete()

多對多

查:

#多對多子表查詢母表,查找小明喜歡哪些顏色--返回:[<Colors: 紅>, <Colors: 黃>, <Colors: 藍(lán)>]
#與一對多子表查詢母表的形式不同,因?yàn)橐粚Χ?,查詢的是母表的“一”;多對多,查詢的是母表的“多?
#寫法1:
child_obj=models.Child.objects.get(name="小明") #寫法:子表對象.子表多對多字段.過濾條件(all()/filter())
print(child_obj.favor.all())
#寫法2,反向從母表入手:
print(models.Colors.objects.filter(child__name="小明")) #母表對象.filter(子表表名小寫__子表字段名="過濾條件")


#多對多母表查詢子表,查找有哪些人喜歡黃色--返回:[<Child: 小明>, <Child: 丫蛋>]
#與一對多母表查詢子表的形式完全一致,因?yàn)椴榈降亩际荙uerySet,一對多和多對多,都是在查詢子表的“多”
#寫法1:
color_obj=models.Colors.objects.get(colors="黃")
print(color_obj.child_set.all())
#寫法2:
print(models.Child.objects.filter(favor=models.Colors.objects.get(colors="黃")))
#寫法2簡便寫法(推薦):
print(models.Child.objects.filter(favor__colors="黃")) #寫法:filter(子表外鍵字段__母表字段='過濾條件')
#寫法3:
color_id=models.Colors.objects.get(colors="黃").id #通過母表獲取到顏色為紅的id
print(models.Child.objects.filter(favor=color_id)) #filter得到QuerySet,寫法:filter(子表外鍵字段=母表主鍵對象),此處和一對多略有不同,是子表外鍵字段而不是外鍵字段_母表主鍵

增與改(增添子表或母表數(shù)據(jù)參照一對一的增,多對多重點(diǎn)在于關(guān)系表的對應(yīng)關(guān)系變更):

#添加子表關(guān)聯(lián)關(guān)系
#添加小虎并讓他喜歡所有顏色
#寫法1:
child_obj=models.Child.objects.create(name="小虎") #如果是已有用戶,使用.get()
colors_obj=models.Colors.objects.all() #創(chuàng)建顏色表的所有顏色QuerySet對象
child_obj.favor.add(*colors_obj) #添加對應(yīng)關(guān)系,將小虎和所有顏色進(jìn)行關(guān)聯(lián),寫法:子表對象.子表多對多字段.add(*QuerySet對象)
#寫法2:
child_obj=models.Child.objects.get(name="小虎")
colors_obj=models.Colors.objects.all()
child_obj.favor=colors_obj
child_obj.save()
#讓小虎喜歡黃色和藍(lán)色(2種寫法和上邊一致,只展示一種寫法)
child_obj=models.Child.objects.get(name="小虎")
colors_obj=models.Colors.objects.filter(colors__in=["藍(lán)","黃"]) #models默認(rèn)只能用這種方式得到并集,如需更復(fù)雜的過濾邏輯,需使用模塊Q
child_obj.favor.clear() #清空小虎已經(jīng)喜歡的顏色
child_obj.favor.add(*colors_obj) #add是追加模式,如果當(dāng)前小虎已經(jīng)喜歡綠色,那么執(zhí)行后,小虎會額外喜歡藍(lán),黃
#讓小虎喜歡綠色(2種寫法和上邊一致,只展示一種寫法)
child_obj=models.Child.objects.get(name="小虎")
colors_obj=models.Colors.objects.get(colors="綠")
child_obj.favor.clear()
child_obj.favor.add(colors_obj) #此處沒有*


#添加母表關(guān)聯(lián)關(guān)系
#讓喜歡藍(lán)色的人里添加小虎,可以用上邊的方法,一個(gè)效果,讓小虎喜歡藍(lán)色,下邊介紹反向插入(從母表入手)的寫法
child_obj=models.Child.objects.get(name="小虎")
colors_obj=models.Colors.objects.get(colors="藍(lán)")
colors_obj.child_set.add(child_obj) #從colors表插入小虎,寫法:母表對象.子表名小寫_set.add(子表對象)。 讓喜歡藍(lán)色的child_set集合添加name="小虎"
#讓所有人都喜歡藍(lán)色
children_obj=models.Child.objects.all()
colors_obj=models.Colors.objects.get(colors="藍(lán)")
colors_obj.child_set.add(*children_obj)
#關(guān)于_set寫法,是否已經(jīng)有些暈了,究竟什么時(shí)候使用_set,簡單記憶,只有子表才有"子表名小寫_set"的寫法,得到的是一個(gè)QuerySet集合,后邊可以接.add(),.remove(),.update(),.delete(),.clear()
#另外備注一下,colors_obj.child_set.clear()是讓所有人喜歡的顏色里去掉藍(lán)色,colors_obj.child_set.all().delete()是刪除.child_set的所有人

刪:

刪除多對多表關(guān)系 :

#刪除子表與母表關(guān)聯(lián)關(guān)系
#讓小虎不喜歡任何顏色
#寫法1:
child_obj=models.Child.objects.get(name="小虎")
colors_obj=models.Colors.objects.all()
child_obj.favor=''
child_obj.save()
#寫法2:
child_obj=models.Child.objects.get(name="小虎")
colors_obj=models.Colors.objects.all()
child_obj.favor.remove(*colors_obj)
#寫法3:
child_obj=models.Child.objects.get(name="小虎")
child_obj.favor.clear()
#其他例子參照多對多的增與改案例,這里不做舉例

#刪除母表與子表關(guān)聯(lián)關(guān)系
#讓所有人不再喜歡藍(lán)色
#寫法1:
children_obj=models.Child.objects.all()
colors_obj=models.Colors.objects.get(colors="藍(lán)")
colors_obj.child_set.remove(*children_obj)
#寫法2:
colors_obj=models.Colors.objects.get(colors="藍(lán)")
colors_obj.child_set.clear()

刪除多對多表數(shù)據(jù):

#刪除子表數(shù)據(jù)
#喜歡藍(lán)色的所有人都刪掉
colors_obj=models.Colors.objects.get(colors="藍(lán)")
colors_obj.child_set.all().delete() #注意有.all()
#刪除所有child
models.Child.objects.all().delete()

刪除母表數(shù)據(jù):

默認(rèn)情況下,如此例中,刪除“紅”色,那么子表與顏色表是一對一或外鍵關(guān)系的,子表對應(yīng)數(shù)據(jù)會自動刪除,如:紅球,小虎哥

與顏色表是多對多關(guān)系的話,不會自動刪除喜歡紅色的人,而是去掉紅色已選

如果想讓與母表外鍵關(guān)聯(lián)的子表在刪除外鍵之后依舊可以保留子表數(shù)據(jù),需要子表建表時(shí)加入以下字段:

class Clothes(models.Model):
 color=models.ForeignKey("Colors",null=True,on_delete=models.SET_NULL)) #可為空,如果外鍵被刪后,子表數(shù)據(jù)此字段置空而不是直接刪除這條數(shù)據(jù),同理也可以SET_DEFAULT,需要此字段有默認(rèn)值
 description=models.CharField(max_length=10) #描述 

choice

#choices相當(dāng)于實(shí)現(xiàn)一個(gè)簡化版的外鍵,外鍵的選項(xiàng)不能動態(tài)更新,如可選項(xiàng)目較少,可以采用
#先在models添加choices字段
class Child(models.Model):
 sex_choice=((0,"男"),(1,"女"))
 name=models.CharField(max_length=10) #姓名
 favor=models.ManyToManyField('Colors') #與顏色表為多對多
 sex=models.IntegerField(choices=sex_choice,default=0)
 def __unicode__(self):
  return self.name

#在views.py中調(diào)用
child_obj=models.Child.objects.get(name="小虎")
print(child_obj.sex) #返回0或1
print(child_obj.get_sex_display()) #返回男或女

以上這篇基于Django ORM、一對一、一對多、多對多的全面講解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python內(nèi)置函數(shù)詳細(xì)解析

    Python內(nèi)置函數(shù)詳細(xì)解析

    這篇文章主要介紹了Python內(nèi)置函數(shù)詳細(xì)解析,Python?自帶了很多的內(nèi)置函數(shù),極大地方便了我們的開發(fā),下文小編總結(jié)了一些內(nèi)置函數(shù)的相關(guān)內(nèi)容,需要的小伙伴可以參考一下
    2022-05-05
  • Windows下的Jupyter Notebook 安裝與自定義啟動(圖文詳解)

    Windows下的Jupyter Notebook 安裝與自定義啟動(圖文詳解)

    這篇文章主要介紹了Windows下的Jupyter Notebook 安裝與自定義啟動(圖文詳解),需要的朋友可以參考下
    2018-02-02
  • Python中打印詳細(xì)堆棧信息的技巧分享

    Python中打印詳細(xì)堆棧信息的技巧分享

    在 Python 開發(fā)過程中,調(diào)試是一個(gè)不可或缺的環(huán)節(jié),當(dāng)代碼出現(xiàn)問題時(shí),能夠快速準(zhǔn)確地定位問題所在是提高開發(fā)效率的關(guān)鍵,堆棧信息作為程序執(zhí)行過程中的調(diào)用記錄,對于理解程序的運(yùn)行狀態(tài)和定位錯(cuò)誤至關(guān)重要,需要的朋友可以參考下
    2024-11-11
  • Python項(xiàng)目文件中安裝?setup.py的步驟

    Python項(xiàng)目文件中安裝?setup.py的步驟

    大家都知道setup.py是python模塊分發(fā)與安裝的指導(dǎo)文件,這篇文章主要介紹了Python項(xiàng)目文件中如何安裝?setup.py,需要的朋友可以參考下
    2023-05-05
  • 對python字典元素的添加與修改方法詳解

    對python字典元素的添加與修改方法詳解

    今天小編就為大家分享一篇對python字典元素的添加與修改方法詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • Python TCP全連接攻擊中SockStress全連接攻擊詳解

    Python TCP全連接攻擊中SockStress全連接攻擊詳解

    Sock Stress 全連接攻擊屬于TCP全連接攻擊,因?yàn)樾枰⒁淮瓮暾腡CP三次握手,該攻擊的關(guān)鍵點(diǎn)就在于,攻擊主機(jī)將windows窗口緩沖設(shè)置為0,實(shí)現(xiàn)的拒絕服務(wù)
    2022-10-10
  • python數(shù)據(jù)預(yù)處理 :數(shù)據(jù)共線性處理詳解

    python數(shù)據(jù)預(yù)處理 :數(shù)據(jù)共線性處理詳解

    今天小編就為大家分享一篇python數(shù)據(jù)預(yù)處理 :數(shù)據(jù)共線性處理詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • pytorch 6 batch_train 批訓(xùn)練操作

    pytorch 6 batch_train 批訓(xùn)練操作

    這篇文章主要介紹了pytorch 6 batch_train 批訓(xùn)練操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python中end=" "的含義及說明

    python中end=" "的含義及說明

    這篇文章主要介紹了python中end=" "的含義及說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • python中super()函數(shù)的理解與基本使用

    python中super()函數(shù)的理解與基本使用

    super( )函數(shù)是用來調(diào)用父類的一個(gè)方法,super( )函數(shù)還用來解決多重繼承的問題,下面這篇文章主要給大家介紹了關(guān)于python中super()函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08

最新評論