Django - ManyToManyField 的反向查找

15 投票
1 回答
14636 浏览
提问于 2025-04-16 11:07

我正在尝试按照Django文档中的代码来做:

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

    def __unicode__(self):
        return self.name

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

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)


>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
...     date_joined=date(1962, 8, 16),
...     invite_reason= "Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
[<Person: Ringo Starr>]
>>> ringo.group_set.all()

我的模型看起来是这样的:

class Trip(models.Model):
    members = models.ManyToManyField(User,blank=True,null=True,through='TripReservation')

但是当我对某个用户实例调用 user.group_set.all() 时,出现了一个错误,提示没有这个属性 group_set。

1 个回答

20

首先,你在用“通过模型”吗?你提到了“通过”,但没有具体列出来。如果你不使用它,那就不需要这个。

我建议加一个相关名称,像这样:

class Trip(models.Model):
    members = models.ManyToManyField(User,blank=True,null=True, related_name='user_trips')

然后你就可以调用:

user.user_trips.all()

我把它叫做“user_trips”,而不是“trips”,因为如果名字不唯一,可能会引起冲突。

如果你在使用“通过模型”,它看起来会更像这样:

#User is defined in django.auth

class Trip(models.Model):
    members = models.ManyToManyField(User,blank=True,null=True, related_name='user_trips', through='TripReservation')

class TripReservation(models.Model):
    user = models.ForeignKey(User)
    trip = models.ForeignKey(Trip)
    registered = models.DateField()

要理解的是,这种方式下,TripReservation是指某个用户对某个旅行的预定,而不是整个旅行的信息,旅行的相关信息应该在Trip模型里。所以,TripReservation.registered是指那个特定用户注册了这个旅行。

用户旅行的查找方式是一样的:

user.user_trips.all()

撰写回答