Django:模型通过中间模型有两个ManyToMany关系

时间:2014-10-18 04:43:36

标签: django django-models

所以我是Django的新手,想要描述一下这个场景:有一堆Persons,还有一堆Items,一个人通过了Items来另一个Person

我有以下型号:

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?但这在直观上没那么明显,因为当项目通过时实际上只有一个事件。

1 个答案:

答案 0 :(得分: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())。