所以我是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
分为GiveEvent
和ReceiveEvent
?但这在直觉上并没有什么意义,因为传递项目时实际上只有一个事件。
您所描述的听起来很合理。这可能是因为技术原因而被禁止;一个语义原因是,每个ManyToManyField
都意味着创建一个新表,并且不可能有两个表具有相同的名称(即由相同的类表示)。
一种替代方法(更短、更干燥)是:
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()
)。