如何在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
相关产品推荐
相关产品推荐

