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

如何在Django框架中获取指定主题下的帖子?

如何在Django中获取主题下的帖子

嘿,我来帮你搞定这个问题!看起来你已经有了基础的模型结构,只是还差一点关联和查询的步骤,咱们一步步来:

第一步:完善模型关联

首先我注意到你的Topic模型里category字段没写完,先补全它,然后咱们需要一个Post模型来关联到Topic(毕竟帖子是属于某个主题的嘛):

# forums/models.py
from django.db import models
from django.contrib.auth.models import User  # 如果需要关联用户的话

class Attachment(models.Model):
    file = models.FileField()
    def __str__(self):
        return self.file.name  # 这里建议返回文件名,比直接返回FileField对象更友好

class Category(models.Model):
    title = models.CharField(max_length=150)
    def __str__(self):
        return self.title

class Topic(models.Model):
    title = models.CharField(max_length=150)
    description = models.TextField()
    # 补全category的ForeignKey,加上related_name方便反向查询
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="topics")
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)  # 可选,主题创建者
    created_at = models.DateTimeField(auto_now_add=True)  # 可选,创建时间

    def __str__(self):
        return self.title

# 新增Post模型,关联到Topic
class Post(models.Model):
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE, related_name="posts")
    content = models.TextField()
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"Post by {self.created_by.username} on {self.topic.title}"

第二步:获取主题下的帖子

有了正确的模型关联后,获取某个主题下的所有帖子就非常简单了,有两种常用方式:

方式1:使用自定义的related_name

我们在Post模型的topic字段里设置了related_name="posts",所以直接通过主题对象调用这个属性就能拿到所有关联的帖子:

# 比如在视图函数中
def topic_detail(request, topic_id):
    # 获取指定主题,用select_related减少数据库查询
    topic = Topic.objects.select_related('category', 'created_by').get(id=topic_id)
    # 获取该主题下的所有帖子,按创建时间排序
    posts = topic.posts.select_related('created_by').order_by('created_at')
    return render(request, 'forums/topic_detail.html', {'topic': topic, 'posts': posts})

方式2:使用Django默认的反向关联名称

如果没有设置related_name,Django会自动生成一个默认的名称:模型名小写_set,也就是post_set,用法类似:

posts = topic.post_set.all().order_by('created_at')

第三步:在模板中展示帖子

最后在模板里遍历帖子列表就可以了:

<!-- forums/topic_detail.html -->
<h1>{{ topic.title }}</h1>
<p class="topic-description">{{ topic.description }}</p>
<p class="topic-meta">
    分类:{{ topic.category.title }} | 作者:{{ topic.created_by.username }} | 创建于:{{ topic.created_at|date:"Y-m-d H:i" }}
</p>

<h2>帖子列表</h2>
{% for post in posts %}
    <div class="post-card">
        <div class="post-header">
            <span>{{ post.created_by.username }}</span>
            <span>{{ post.created_at|date:"Y-m-d H:i" }}</span>
            {% if post.updated_at != post.created_at %}
                <span>更新于:{{ post.updated_at|date:"Y-m-d H:i" }}</span>
            {% endif %}
        </div>
        <div class="post-content">
            {{ post.content|linebreaks }}
        </div>
    </div>
{% empty %}
    <p>这个主题还没有任何帖子,快来发第一个帖子吧!</p>
{% endfor %}

小提示:使用select_related可以减少数据库查询次数,提升页面加载性能,尤其是当你需要关联查询用户、分类这些外键数据的时候。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:28:25