如何在Django的User、Post与Comments间实现多对多关系?
解决方案
修改后的模型代码
from django.contrib.auth.models import User from django.db import models class Post(models.Model): title = models.CharField(max_length=50) desc = models.TextField(max_length=200) views = models.IntegerField(default=0) answers = models.IntegerField(default=0) view_status = models.BooleanField(default=False) author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts') post_image = models.ImageField(upload_to='upload/images') # 多对多关系:记录点赞该帖子的用户 liked_by = models.ManyToManyField(User, related_name='liked_posts', blank=True) def __str__(self): return self.title @property def likes(self): # 动态计算点赞数,替代原手动维护的IntegerField return self.liked_by.count() class Comments(models.Model): comment = models.TextField(max_length=500) post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments') def __str__(self): return f"评论{self.id} by {self.author.username}"
关键修改说明
Post模型优化
- 把
related_name='users'改为related_name='posts',语义更清晰:通过user.posts.all()可直接获取该用户发布的所有帖子。 - 新增
liked_by多对多字段,实现用户与帖子的点赞关联,避免原likes字段手动维护导致的数据不一致问题,通过@property动态计算点赞数。 - 重写
__str__返回帖子标题,便于后台管理查看。
- 把
Comments模型完善
- 添加
author字段关联User,明确评论发布者,通过user.comments.all()可获取该用户的所有评论。 - 移除手动生成
cmnt_id的逻辑,改用Django默认自增主键,避免并发场景下重复ID的问题,简化代码。 - 将
pid重命名为post,字段命名更符合规范。
- 添加
按帖子维度维护数据的示例
- 获取某用户发布的所有帖子及对应评论:
# 假设user_obj是目标用户对象 user_posts = user_obj.posts.all() for post in user_posts: post_comments = post.comments.all() print(f"帖子:{post.title},评论数:{post_comments.count()}")
- 获取某帖子下的所有评论及评论作者:
# 假设post_obj是目标帖子对象 post_comments = post_obj.comments.all() for comment in post_comments: print(f"评论作者:{comment.author.username},内容:{comment.comment}")
- 实现用户点赞/取消点赞(自动防重复):
# 点赞 if not post_obj.liked_by.filter(id=user_obj.id).exists(): post_obj.liked_by.add(user_obj) # 取消点赞 post_obj.liked_by.remove(user_obj)
内容的提问来源于stack exchange,提问作者Py King
相关产品推荐
相关产品推荐

