You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django DetailView中展示单个主题的多条Entry

问题分析

你当前的ContentDetailView继承自DetailView且绑定的是Entries模型,所以它只会根据传入的pk获取单条Entry记录,这就是只能显示一条内容的核心原因。要实现点击主题后展示该主题下的所有Entry,需要把DetailView绑定到Topic模型,再通过Django的反向关联获取该主题对应的所有Entry。

解决方案步骤

1. 修改views.py

将详情视图改为基于Topic模型的DetailView,这样就能获取指定主题对象,后续可通过它关联所有Entry:

# views.py
from django.views.generic import ListView, DetailView
from .models import Topic, Entries

class TopicListView(ListView):
    model = Topic
    template_name = 'cms_app/topic_list.html'
    context_object_name = 'topics'  # 改为复数形式,语义更准确

class TopicDetailView(DetailView):
    model = Topic
    template_name = 'cms_app/topic_detail.html'  # 模板名对应主题详情,更清晰
    context_object_name = 'topic'

2. 修改urls.py

更新URL配置,将详情页视图替换为新的TopicDetailView,路径参数保持为Topic的pk:

# urls.py
from django.urls import path
from .views import TopicListView, TopicDetailView

urlpatterns = [
    path('', TopicListView.as_view(), name='all-topic'),
    path('content/<int:pk>', TopicDetailView.as_view(), name='all-content'),
]

3. 调整主题列表模板(topic_list.html)

把循环变量的上下文名改为topics,和ListView的配置对应:

<!-- topic_list.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>All Topics</title>
</head>
<body>
    <h1>Topic List</h1>
    <h3>
    {% for data in topics %}
        <p><a href="{% url 'all-content' data.id %}">{{ data.title }}</a></p>
    {% endfor %}
    </h3>
</body>
</html>

4. 创建主题详情模板(topic_detail.html)

通过Django自动生成的反向关联属性topic.entries_set.all,遍历该主题下的所有Entry:

<!-- topic_detail.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ topic.title }} - All Contents</title>
</head>
<body>
    <h1>{{ topic.title }}</h1>
    {% for entry in topic.entries_set.all %}
        <div class="entry">
            <p>{{ entry.text }}</p>
            {% if entry.image %}
                <img src="{{ entry.image.url }}" alt="Entry image">
            {% endif %}
            <p>Added on: {{ entry.date_added }}</p>
            <hr>
        </div>
    {% empty %}
        <p>No entries for this topic yet.</p>
    {% endfor %}
</body>
</html>

可选优化:自定义反向关联名称

如果觉得entries_set不够直观,可在Entries模型的外键字段添加related_name参数:

# models.py
class Entries(models.Model):
    '''Entries and Topic will have many to one relationship'''
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE, related_name='entries')
    text = models.TextField()
    image = models.ImageField(upload_to='images', blank=True)
    date_added = models.DateTimeField(auto_now_add=True)

之后在模板中就可以用topic.entries.all代替topic.entries_set.all,语义更清晰。

内容的提问来源于stack exchange,提问作者Trishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:52:30