如何从django模板访问多对多“through”表的属性?
从Django文档...如何从django模板访问多对多“through”表的属性?
当你只处理简单许多一对多的关系,如混合和匹配比萨和浇头,一个标准的ManyToManyField是你所需要的。但是,有时您可能需要将数据与两个模型之间的关系相关联。
例如,考虑跟踪音乐家属于哪个音乐组的应用程序的情况。在一个人和他们所属的小组之间存在多对多的关系,因此您可以使用ManyToManyField来表示这种关系。但是,关于您可能想要收集的会员资格有很多详细信息,例如加入该组的人的日期。
对于这些情况,Django允许您指定将用于管理多对多关系的模型。然后您可以在中间模型上添加额外的字段。中间模型使用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使用您的中介者模式(会员,在这种情况下),你就可以开始创建一些多对多的关系。通过创建中间模型的实例做到这一点:
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
我的问题是,我该如何设置我的观点和模板来访问这些附加属性。假设我有一个乐队页面,我想显示乐队名称,遍历成员资格记录并显示姓名和date_joined。
我应该将带对象传递给模板吗?或者我以某种方式传递会员对象?
如何在模板中创建for循环?
谢谢。
最简单的方法就是将乐队传递给模板。模板能够导航模型之间的关系,Group上有成员和membership_set查询集管理器。因此,这里是我会怎么做:
观点:
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 %}
我不确定它是否只是解决方案,但将关系对象传递给模板当然有效。在你看来,得到查询集成员的对象:
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()
的任何其他查询。
我会考虑缩短从Django文档有点摘录。有可能回复的人可能已经对他们很熟悉了,这样就更容易找到真正的问题。 – cji 2010-07-30 04:57:37