2014-10-18 117 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

相关问题