1. 程式人生 > >ORM表多對多的操作

ORM表多對多的操作

django orm

了解學習下表的多對多的操作練習

創建表結構

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=‘小藍‘),
        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)

通過瀏覽器訪問test頁面,執行數據插入

查詢

查詢張三封的對應的女孩的名字列表
第一種方法:

select_result = models.Boy.objects.filter(name=‘張三封‘).first()
    select_loveinfo = select_result.love_set.all()# 這裏通過表明+set方法反向查找
    for item in select_loveinfo:#循環的時候就跨表了
        print(item.g.nick)

第二種方法:

objs = models.Love.objects.filter(b__name=‘張三封‘)
    for row in objs:#循環的時候就跨表了
        print(row.g.nick)

第三種方法:

objs = models.Love.objects.filter(b__name=‘張三封‘).values(‘g__nick‘)#查詢的時候就指定了,減少了查詢次數
    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)

添加約束條件

加上聯合索引,就不能多次關聯,(約會了)

class Love(models.Model):
    b = models.ForeignKey(‘Boy‘)
    g = models.ForeignKey(‘Girls‘)
    class Meta:
        unique_together = [
            (‘b‘,‘g‘),
        ]

django自帶生成多對多的表

上面的案例是我們手動去生成了一個關系表,來關聯多個表。django可以自動給生成一個多對多的關系表
首先我們班上面的Love表註釋掉。然後讓django來自動創建

class Girls(models.Model):
    nick = models.CharField(max_length=32)
    m = models.ManyToManyField(‘Boy‘)#這一句diango就可以幫忙生成一個關系表。這個語句寫到任何一個關聯表裏面都可以,如下面Boy表裏面的m

class Boy(models.Model):
    name = models.CharField(max_length=32)
    #m = models.ManyToManyField(‘Girls‘)

創建上面的代碼後,執行makemigrations和migrate,來生成表,然後可以看到生成了一個表,如下圖
技術分享圖片

給第三張表插入數據

由於沒有第三張表對應的類,所以不能直接操作第三張表。所以我們也間接的去操作。
首先我們從Boy表裏面取一個值,然後根據這個對象和這個表裏面的m來連接到第三張表裏面,如下:給第三張表添加數據

 obj = models.Boy.objects.filter(name=‘張三封‘).first()
    print(obj.id,obj.name) #這裏可以看到name為“張三封”對應的id值
obj = models.Boy.objects.filter(name=‘張三封‘).first()
    print(obj.id,obj.name)# 通過對象 然後m來關聯第三張表
    obj.m.add(3)#通過add來給第三張表添加數據

可以看到對應“張三封”的id對應的girls的id添加到了第三張表裏面
技術分享圖片

add可以添加多個值,也可以添加列表eg:obj.m..add(2,4)或者obj.m.add(*[1,3,5,])

第三張表的刪除

刪除使用obj.m.remove(*args,),值可以是單個值,也可以是多個或者是列表

第三張表的修改

修改使用的是obj.m.set(*args),值是必須能叠代的值,可以是列表。set是重置的,會把所有的都弄成set的值

第三張表的獲取

obj = models.Boy.objects.filter(name=‘張三封‘).first()
    print(obj.id,obj.name)
    q = obj.m.all()#這裏獲取的是girl表的對象,也就是另外一個表的對象。只有類才可以生成對象
    print(q)#這裏可以看到是girl的對象
    for xx in q:
        print(xx.nick)

技術分享圖片

q = obj.m.filter(id=‘1‘),這裏也可以繼續篩選,
q = obj.m.clear(),這個是吧和張三封有關的都全部清除了

反向查找

多對多也是可以反向查找的通過小寫的表名字+set

   obj = models.Girls.objects.all().filter(nick=‘小綠‘).first()
    q = obj.boy_set.all()
    print(q)

技術分享圖片

如果想要第三張表更加靈活,要自定義,如果對第三張表以後不會增加列,就可以用django 自帶的

自帶和自定義的聯合使用

在設計的時候使用了自帶的manytomany的同時,自己也要設計第三張表。這個時候要給manytomany來設置一些參數,如下
技術分享圖片

這裏面添加了參數就不會生成第四張表。如果不加這個參數through,就會出現一共4張表的.這個時候,不能使用第
三張表的m.add(1)來添加,會有下面的報錯:(clear,all可以,但是set,remove,add都是不可以的)
技術分享圖片
技術分享圖片

ORM表多對多的操作