2013-07-23 40 views
2

我不明白爲什麼我們必須使用ManyToManyField來聲明多對多關聯。爲此,我將創建另一個帶有兩個外鍵的表格,即句號! 下面是一個例子從DOC https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany多對多協會

from django.db import models 

class Person(models.Model): 
    name = models.CharField(max_length=128) 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership') 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    extraField = models.DateField() 

我只想寫:

from django.db import models 

class Person(models.Model): 
    name = models.CharField(max_length=128) 

class Group(models.Model): 
    name = models.CharField(max_length=128) 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    extraField = models.DateField() 

它是正確的嗎?有什麼不同?

+0

我讓別人回答這個誰更有資格。很好的問題。 – jdero

+0

正確的方法是使用'ManyToManyField'來完成它,因爲在你的情況下製作稱爲'Membership'的額外模型非常繁瑣。 –

回答

2

定義關係的中間模型沒有任何問題。通過這種方式,您可以在中間模型(「會員」)上存儲額外信息,例如加入該羣組的人員或會員資格仍然有效。但是,大多數情況下,您不需要額外的信息,只需要存儲哪個人是哪個組的成員。在這些情況下,您可以使用簡單的ManyToManyField。 Django的使得它很容易與這些領域的工作,所以你可以做group.members.add(user)group.members.delete(user),比較,爲:

Membership.objects.create(user=user, group=group) 
Membership.objects.get(user=user, group=group).delete() 

免責聲明:僞代碼,可能不實際工作

您仍然可以使用ManyToManyField與中間模式,這使得大多數Django的多對多的便利,但也有一些限制:

不同於一般的多到很多領域,你不能使用添加,創建或轉讓(即甲殼蟲。成員= [...])來建立關係。

爲什麼?您不能僅在Person和Group之間創建關係 - 您需要指定Membership模型所需關係的所有詳細信息。簡單的添加,創建和賦值調用不提供指定這些額外細節的方法。因此,它們在使用中間模型的多對多關係中被禁用。創建這種類型的關係的唯一方法是創建中間模型的實例。

出於類似的原因,remove()方法被禁用。但是,clear()方法可用於刪除實例的所有多對多關係。

一旦通過創建中間模型的實例建立了多對多關係,就可以發出查詢。與正常的多對多關係一樣,您可以使用多對多關聯模型的屬性進行查詢。

來源:docs.djangoproject.com

+0

好了,所以它只是一個快捷方式......如果我們想創建中間表(使用外鍵)......是否仍然需要使用ManyToManyField? – rom

+0

如果你有自己創建的中間模型,'ManyToManyField(through = ...)'是可選的。它仍然爲您提供了大部分快捷方式,但無法創建新的關係。另見我的編輯。 – bouke

+0

我現在明白了,最好使用ManyToManyField來訪問django快捷方式來操作模型。謝謝! – rom