如何从django模板访问多对多“through”表的属性?

从Django文档…

当你只处理简单的多对多关系时,比如混合和匹配比萨饼和浇头,一个标准的ManyToManyField就是你所需要的。 但是,有时您可能需要将数据与两个模型之间的关系相关联。

例如,考虑跟踪音乐家所属的音乐组的应用的情况。 一个人和他们所属的小组之间有多对多的关系,所以你可以使用ManyToManyField来表示这种关系。 但是,关于您可能想要收集的会员资格有很多详细信息,例如join该组的人员的date。

对于这些情况,Django允许您指定将用于pipe理多对多关系的模型。 然后可以在中间模型上添加额外的字段。 中间模型使用through参数与ManyToManyField关联,指向将作为中介的模型。 对于我们音乐家的例子,代码看起来像这样:

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) 

现在您已经设置了ManyToManyField来使用您的中介模型(在这种情况下为Membership),您可以开始创build一些多对多的关系。 您可以通过创build中间模型的实例来执行此操作:

 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() [<Group: The Beatles>] m2 = Membership.objects.create(person=paul, group=beatles, ... date_joined=date(1960, 8, 1), ... invite_reason= "Wanted to form a band.") beatles.members.all() [<Person: Ringo Starr>, <Person: Paul McCartney>] 

来源: http : //docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

我的问题是,如何设置我的视图和模板来访问这些额外的属性。 假设我有一个乐队页面,我想显示乐队名称,迭代成员logging并显示名称和date_joined。

我应该将乐队对象传递给模板吗? 还是以某种方式传递会员对象?

我将如何在模板中创buildfor循环?

谢谢。

最简单的方法就是将乐队传递给模板。 模板能够导航模型之间的关系,Group上有成员和membership_set查询集pipe理器。 所以这里是我如何做到这一点:

视图:

 def group_details(request, group_id): group = get_object_or_404(Group, pk=group_id) return render_to_response('group_details.html', {'group': group}) 

模板:

 <h2>{{ group.name }}</h2> {% for membership in group.membership_set.all %} <h3>{{ membership.person }}</h3> {{ membership.date_joined }} {% endfor %} 

我不确定是否只有解决scheme,但将关系对象传递给模板当然有效。 在你看来,获取Membership对象的QuerySet:

 rel = Membership.objects.filter( group = your_group ).select_related() 

并将其传递给模板,您可以在其中使用{% for %}来遍历它

 {% for r in rel %} {{ r.person.name }} joined group {{ r.group.name }} on {{ r.date_joined }}<br /> {% endfor %} 

请注意,这不应该由于select_related()而执行任何其他查询。