2014-10-18 113 views
9

所以,我是新來的Django,並要描述的場景:有一堆Persons,並有一堆Items,和人通過Items另一個PersonDjango的:模型有通過中間模型中的兩個多對多關係

我有以下型號:

class Item(models.Model): 
    title = models.CharField(max_length=1024, blank=False) 

    def __unicode__(self): 
     return self.title 

class Person(models.Model): 
    name = models.CharField(max_length=127, blank=False) 
    out_item = models.ManyToManyField(
     Item, 
     through='Event', 
     through_fields=('from_user', 'item'), 
     related_name='giver' 
    ) 
    in_item = models.ManyToManyField(
     Item, 
     through='Event', 
     through_fields=('to_user', 'item'), 
     related_name='receiver' 
    ) 

    def __unicode__(self): 
     return self.name 

class Event(models.Model): 
    item = models.ForeignKey(Item) 
    from_user = models.ForeignKey(Person, related_name='event_as_giver') 
    to_user = models.ForeignKey(Person, related_name='event_as_receiver') 

makemigrations告訴我app.Person: (models.E003) The model has two many-to-many relations through the intermediate model 'app.Event'.

我不知道我做錯了什麼?或者什麼是實現這種情況的乾淨方式?也許我可以將Event分成GiveEventReceiveEvent?但是這隻會讓直覺變得不那麼直觀,因爲當物品通過時實際上只有一個事件。

+0

看來,新的Django System Check框架在同一個模型上使用相同的「through」模型不接受兩個多對多字段。所以這就是爲什麼這個錯誤信息表明失敗。這意味着您的案件的預期行爲。但是我想知道爲什麼它以這種方式實現並禁止它..好問題.. – 2014-10-18 05:17:12

回答

5

你所描述的聽起來很合理。可能有技術上的原因,爲什麼不允許這樣做;一個語義原因是每個ManyToManyField意味着創建一個新表,並且不能有兩個具有相同名稱的表(即由相同類表示)。

一種替代的方法(更短和更DRY)會是這樣:

class Person(models.Model): 
    name = models.CharField(max_length=127, blank=False) 
    to_users = models.ManyToManyField(
     'self', 
     symmetrical=False, 
     related_name='from_users', 
     through='Event', 
     through_fields=('from_user', 'to_user'), 
    ) 

class Event(models.Model): 
    item = models.ForeignKey(Item, related_name='events') 
    from_user = models.ForeignKey(Person, related_name='events_as_giver') 
    to_user = models.ForeignKey(Person, related_name='events_as_receiver') 

表結構是相同的,但描述是不同的。訪問相關是一個更容易,但訪問相關的是有點困難(例如,而不是person.out_items.all(),你會說Item.objects.filter(events__from_user=person).distinct())。

+0

行Item'objects.filter(events__from_user = person).distinct()'不工作..... person not defined – 2016-01-16 13:12:34