您好,登錄后才能下訂單哦!
了解學(xué)習(xí)下表的多對(duì)多的操作練習(xí)
class Girls(models.Model):
nick = models.CharField(max_length=32)
class Boy(models.Model):
name = models.CharField(max_length=32)
class Love(models.Model):
b = models.ForeignKey('Boy')
g = models.ForeignKey('Girls ')
obsboy=[
models.Boy(name='張三封'),
models.Boy(name='李東寶'),
models.Boy(name='郭三貼'),
models.Boy(name='劉能'),
]
models.Boy.objects.bulk_create(obsboy,5)
obsgirl=[
models.Girls(nick='小紅'),
models.Girls(nick='小藍(lán)'),
models.Girls(nick='小綠'),
models.Girls(nick='小紫')
]
models.Girls.objects.bulk_create(obsgirl,4)
models.Love.objects.create(b_id=1,g_id=2)
models.Love.objects.create(b_id=2,g_id=3)
models.Love.objects.create(b_id=3,g_id=1)
models.Love.objects.create(b_id=4,g_id=4)
models.Love.objects.create(b_id=1,g_id=4)
通過(guò)瀏覽器訪問(wèn)test頁(yè)面,執(zhí)行數(shù)據(jù)插入
查詢張三封
的對(duì)應(yīng)的女孩的名字列表
第一種方法:
select_result = models.Boy.objects.filter(name='張三封').first()
select_loveinfo = select_result.love_set.all()# 這里通過(guò)表明+set方法反向查找
for item in select_loveinfo:#循環(huán)的時(shí)候就跨表了
print(item.g.nick)
第二種方法:
objs = models.Love.objects.filter(b__name='張三封')
for row in objs:#循環(huán)的時(shí)候就跨表了
print(row.g.nick)
第三種方法:
objs = models.Love.objects.filter(b__name='張三封').values('g__nick')#查詢的時(shí)候就指定了,減少了查詢次數(shù)
for row in objs:
print(row['g__nick'])
第四種方法:
objs = models.Love.objects.filter(b__name='張三封').select_related('g')
for row in objs:
print(row.g.nick)
第五中方法:
objs = models.Love.objects.filter(b__name='張三封').prefetch_related('g')
for row in objs:
print(row.g.nick)
加上聯(lián)合索引,就不能多次關(guān)聯(lián),(約會(huì)了)
class Love(models.Model):
b = models.ForeignKey('Boy')
g = models.ForeignKey('Girls')
class Meta:
unique_together = [
('b','g'),
]
上面的案例是我們手動(dòng)去生成了一個(gè)關(guān)系表,來(lái)關(guān)聯(lián)多個(gè)表。django可以自動(dòng)給生成一個(gè)多對(duì)多的關(guān)系表
首先我們班上面的Love表注釋掉。然后讓django來(lái)自動(dòng)創(chuàng)建
class Girls(models.Model):
nick = models.CharField(max_length=32)
m = models.ManyToManyField('Boy')#這一句diango就可以幫忙生成一個(gè)關(guān)系表。這個(gè)語(yǔ)句寫(xiě)到任何一個(gè)關(guān)聯(lián)表里面都可以,如下面Boy表里面的m
class Boy(models.Model):
name = models.CharField(max_length=32)
#m = models.ManyToManyField('Girls')
創(chuàng)建上面的代碼后,執(zhí)行makemigrations和migrate,來(lái)生成表,然后可以看到生成了一個(gè)表,如下圖
由于沒(méi)有第三張表對(duì)應(yīng)的類,所以不能直接操作第三張表。所以我們也間接的去操作。
首先我們從Boy表里面取一個(gè)值,然后根據(jù)這個(gè)對(duì)象和這個(gè)表里面的m來(lái)連接到第三張表里面,如下:給第三張表添加數(shù)據(jù)
obj = models.Boy.objects.filter(name='張三封').first()
print(obj.id,obj.name) #這里可以看到name為“張三封”對(duì)應(yīng)的id值
obj = models.Boy.objects.filter(name='張三封').first()
print(obj.id,obj.name)# 通過(guò)對(duì)象 然后m來(lái)關(guān)聯(lián)第三張表
obj.m.add(3)#通過(guò)add來(lái)給第三張表添加數(shù)據(jù)
可以看到對(duì)應(yīng)“張三封”的id對(duì)應(yīng)的girls的id添加到了第三張表里面
add可以添加多個(gè)值,也可以添加列表eg:obj.m..add(2,4)或者obj.m.add(*[1,3,5,])
刪除使用obj.m.remove(*args,),值可以是單個(gè)值,也可以是多個(gè)或者是列表
修改使用的是obj.m.set(*args),值是必須能迭代的值,可以是列表。set是重置的,會(huì)把所有的都弄成set的值
obj = models.Boy.objects.filter(name='張三封').first()
print(obj.id,obj.name)
q = obj.m.all()#這里獲取的是girl表的對(duì)象,也就是另外一個(gè)表的對(duì)象。只有類才可以生成對(duì)象
print(q)#這里可以看到是girl的對(duì)象
for xx in q:
print(xx.nick)
q = obj.m.filter(id='1'),這里也可以繼續(xù)篩選,
q = obj.m.clear(),這個(gè)是吧和張三封有關(guān)的都全部清除了
多對(duì)多也是可以反向查找的通過(guò)小寫(xiě)的表名字+set
obj = models.Girls.objects.all().filter(nick='小綠').first()
q = obj.boy_set.all()
print(q)
如果想要第三張表更加靈活,要自定義,如果對(duì)第三張表以后不會(huì)增加列,就可以用django 自帶的
在設(shè)計(jì)的時(shí)候使用了自帶的manytomany的同時(shí),自己也要設(shè)計(jì)第三張表。這個(gè)時(shí)候要給manytomany來(lái)設(shè)置一些參數(shù),如下
這里面添加了參數(shù)就不會(huì)生成第四張表。如果不加這個(gè)參數(shù)through,就會(huì)出現(xiàn)一共4張表的.這個(gè)時(shí)候,不能使用第
三張表的m.add(1)來(lái)添加,會(huì)有下面的報(bào)錯(cuò):(clear,all可以,但是set,remove,add都是不可以的)
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。