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

如何在Python项目中仅展示用户订阅的博客文章

问题:仅展示当前用户已订阅账号的博客文章

我有两个Python应用,分别用于博客文章和用户资料管理。希望在HTML主页仅展示当前用户已订阅账号的博客文章。

现有代码

博客文章 models.py

class News(models.Model):
    user = models.ForeignKey(
        User,
        related_name='user_news',
        on_delete=models.CASCADE
    )
    title = models.CharField(
        max_length=250
    )
    description = RichTextField()

    def __str__(self) -> str:
        return self.title

    def save(self, *args, **kwargs):
        updating = self.pk is not None

博客文章 views.py

def home(request):
    blogs= Blog.objects.order_by('-created_date')
    users = User.objects.order_by('-date_joined')

    context = {
        "blogs": blogs,
        'users': users,
    }
    return render(request, 'home.html', context)

用户资料 models.py

class User(AbstractUser):

    followers = models.ManyToManyField("Follow")

    def __str__(self):
        return self.username


class Follow(models.Model):
    followed = models.ForeignKey(
        User,
        related_name='user_followers',
        on_delete=models.CASCADE
    )
    followed_by = models.ForeignKey(
        User,
        related_name='user_follows',
        on_delete=models.CASCADE
    )

    def __str__(self) -> str:
        return f"{self.followed_by.username} started following {self.followed.username}"

用户资料 views.py

def follow_or_unfollow_user(request, user_id):
    followed = get_object_or_404(User, id=user_id)
    followed_by = get_object_or_404(User, id=request.user.id)

    follow, created = Follow.objects.get_or_create(
        followed=followed,
        followed_by=followed_by
    )

    if created:
        followed.followers.add(follow)

    else:
        followed.followers.remove(follow)
        follow.delete()

    return redirect("view_user_information", username=followed.username)

尝试的模板代码(无法正常展示订阅文章)

<div class="swiper-wrapper">
        {% for blog in account.user_blogs.all %}
        {% for blog in blogs|slice:"2" %}
        
        <div
          
          class="swiper-slide subscription-card"
        >
        <a href="{% url 'news_details' new.slug %}">
          <div class="subscription-card__header">
            <div>
              <h5>{{blog.user.first_name}} {{blog.user.last_name}}</h5>
              <span>{{blog.created_date}}</span>
            </div>
          </div>
          <div class="subscription-card__body">
            <img
              src="{{blog.banner.url}}"
              alt=""
            />
            <h5>{{blog.title|truncatechars:30}}</h5>
          </div>
        </a>
        {% endfor %}
        {% endfor %}
      </div>

{% for blog in blogs|slice:"2" %} 可以正常展示全部文章,但我想要实现类似{% for blog in account.followers.user_blogs.all %}的效果,仅展示订阅用户的博客文章。


解决方案

1. 修正用户关注模型关联

现有模型中User.followers关联的是Follow对象而非用户,导致无法直接获取关注的用户列表。重新定义模型:

from django.contrib.auth.models import AbstractUser
from django.db import models

class User(AbstractUser):
    # 建立用户间的关注关系:当前用户关注的用户
    following = models.ManyToManyField(
        'self',
        through='Follow',
        symmetrical=False,
        related_name='followers'
    )

    def __str__(self):
        return self.username


class Follow(models.Model):
    followed = models.ForeignKey(
        User,
        related_name='followed_relationships',
        on_delete=models.CASCADE
    )
    followed_by = models.ForeignKey(
        User,
        related_name='following_relationships',
        on_delete=models.CASCADE
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('followed', 'followed_by')  # 避免重复关注

    def __str__(self) -> str:
        return f"{self.followed_by.username} 关注了 {self.followed.username}"

2. 修正关注/取消关注视图

利用Django多对多中间表的特性简化逻辑:

from django.shortcuts import get_object_or_404, redirect
from .models import User, Follow

def follow_or_unfollow_user(request, user_id):
    followed = get_object_or_404(User, id=user_id)
    followed_by = request.user

    if followed == followed_by:
        return redirect("view_user_information", username=followed.username)

    follow, created = Follow.objects.get_or_create(
        followed=followed,
        followed_by=followed_by
    )

    if not created:
        follow.delete()

    return redirect("view_user_information", username=followed.username)

3. 修改主页视图过滤订阅用户的文章

在视图中直接过滤出当前用户关注的用户发布的文章:

from django.shortcuts import render
from .models import News, User

def home(request):
    if request.user.is_authenticated:
        # 获取当前用户关注的所有用户
        followed_users = request.user.following.all()
        # 过滤这些用户的文章并按创建时间倒序
        blogs = News.objects.filter(user__in=followed_users).order_by('-created_date')
    else:
        # 未登录时可展示全部文章或空,按需调整
        blogs = News.objects.order_by('-created_date')
    
    users = User.objects.order_by('-date_joined')

    context = {
        "blogs": blogs,
        'users': users,
    }
    return render(request, 'home.html', context)

4. 简化模板代码

直接遍历视图中已过滤好的文章列表:

<div class="swiper-wrapper">
    {% for blog in blogs|slice:"2" %}
    <div class="swiper-slide subscription-card">
        <a href="{% url 'news_details' blog.slug %}">
            <div class="subscription-card__header">
                <div>
                    <h5>{{ blog.user.first_name }} {{ blog.user.last_name }}</h5>
                    <span>{{ blog.created_date }}</span>
                </div>
            </div>
            <div class="subscription-card__body">
                <img src="{{ blog.banner.url }}" alt="{{ blog.title }}">
                <h5>{{ blog.title|truncatechars:30 }}</h5>
            </div>
        </a>
    </div>
    {% empty %}
    <p>你还没有关注任何用户,快去关注一些博主吧!</p>
    {% endfor %}
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:55:02