我有3个模型遵循Django文档(https://docs.djangoproject.com/en/2.2/topics/db/models/#extra-fields-on-many-to-many-relationships)中描述的原理:
class Topic(models.Model):
key = models.CharField(max_length=255, primary_key=True)
persons = models.ManyToManyField('Person', through='Interest')
class Person(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
interests = models.ManyToManyField('Topic', through='Interest')
class Interest(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
source = models.ForeignKey(TopicSource, on_delete=models.CASCADE)
views.py
非常简单:
class TopicsView(generic.ListView):
template_name = 'app/topics.html'
context_object_name = 'topics_list'
def get_queryset(self):
return Topic.objects.all()
模板实际上让我头疼:
<table>
<tbody class="list">
{% for item in topics_list %}
<tr>
<td>{{ item.key }}</td>
<td>{{ item.person_set.all.count }}</td>
<td>
<ul>
{% for person in item.person_set.all %}
<li>{{ person.last_name }}, {{ person.first_name }} [{% person.interests_set.get(cluster=item) %}]</li>{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
使用{% person.interests_set.get(topic=item) %}
,我试图访问中间表中的数据。
如何在人名旁边显示source
中的interest
?
This solution在shell中提供了有关如何执行此操作的提示,但我不知道如何在模板中实现。
答案 0 :(得分:2)
Django模板不支持您尝试开箱即用的功能。您必须创建自定义tag才能实现您要尝试的功能。
无论如何,您都可以这样做:
class TopicsView(generic.ListView):
template_name = 'app/topics.html'
context_object_name = 'topics_list'
queryset = Topic.objects.prefetch_related(
Prefetch(
'interest_set',
Interest.objects.select_related('person')
)
然后调整模板以遍历兴趣。
<table>
<tbody class="list">
{% for item in topics_list %}
<tr>
<td>{{ item.key }}</td>
<td>{{ item.interest_set.all.count }}</td>
<td>
<ul>
{% for interest in item.interest_set.all %}
<li>{{ interest.person.last_name }}, {{ interest.person.first_name }} [ {{ interest.source }} ]</li>{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
答案 1 :(得分:0)
作为@schillingt提出的解决方案(公认的解决方案)的替代方案,我提出了以下解决方案:
views.py
:
class InterestsView(generic.ListView):
template_name = 'app/interests.html'
context_object_name = 'interests_list'
def get_queryset(self):
return Interest.objects.order_by('topic', 'person').all()
模板:
{% regroup interests_list by topic as l1%}
<table>
<tbody>
{% for topic in l1 %}
<tr>
<td>{{ topic.grouper }}</td>
<td>{{ topic.list|length }}</td>
<td>
<ul>
{% for item in topic.list%}
<li>{{ item.person.last_name }}, {{ item.person.first_name }} [{{ item.source }}]</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
但是,@ schillingt的解决方案更好,因为它的性能要好很多(系数2),