一尘不染

如何从Django模板访问多对多“通过”表的属性?

django

从Django文档中…

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

例如,考虑一个应用程序跟踪音乐家所属的音乐团体的情况。一个人与其所属的组之间存在多对多关系,因此你可以使用ManyToManyField表示这种关系。但是,关于你可能希望收集的成员资格,有很多详细信息,例如该人加入该组的日期。

对于这些情况,Django允许你指定将用于管理多对多关系的模型。然后,你可以在中间模型上放置额外的字段。使用直通参数将中间模型与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),你就可以开始创建一些多对多关系了。你可以通过创建中间模型的实例来做到这一点:

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>]

我的问题是,如何设置视图和模板来访问这些其他属性。说我有一个乐队页面,我想显示乐队名称,遍历成员资格记录并显示名称和date_joined。

我应该将band对象传递给模板吗?还是我以某种方式传递成员资格对象?

以及如何在模板中创建for循环?


阅读 716

收藏
2020-04-03

共1个答案

一尘不染

最简单的方法就是将波段传递给模板。模板具有导航模型之间的关系的能力,并且Group上既有Member也有Membership_set queryset管理器。所以这是我要怎么做:

视图:

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 %}
2020-04-03