Django用户间评论功能开发遇错求助:外键错误与评论归属问题
Django 用户主页评论功能修复方案
核心问题分析
你遇到的两个问题根源在于:
- Profile和User的关联关系错误(用了ForeignKey而非一对一),导致创建评论时无法正确关联目标用户的Profile;
- 视图中创建评论时传错了字段值,获取评论的关联查询逻辑也错了。
分步修复
1. 修正Profile模型的关联逻辑
一个用户应该对应唯一的个人主页,所以Profile和User要用OneToOneField而非ForeignKey,同时添加related_name方便反向查询:
class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') def __str__(self): return self.user.username
2. 优化Review模型的字段命名(可选但更清晰)
把字段名改成更直观的命名,避免混淆:
class Review(models.Model): reviewer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='given_reviews') # 评论者 target_profile = models.ForeignKey(Profile, on_delete=models.SET_NULL, null=True, related_name='received_reviews') # 被评论者的Profile reviewmsg = models.TextField(null=True, blank=True) updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) def __str__(self): return f"{self.reviewer.username} 给 {self.target_profile.user.username} 的评论"
3. 修复视图中的两个关键错误
错误1:创建评论时传值错误
原来的profile=user是把User实例传给了需要Profile的字段,改成目标用户的Profile实例:
# 替换创建评论的代码 Review.objects.create( reviewer=request.user, target_profile=user.profile, reviewmsg=request.POST.get('reviewmsg') )
错误2:获取评论的逻辑错误
原来从User反向查Review是错的,应该从目标用户的Profile查收到的评论:
# 替换评论查询代码 reviews = user.profile.received_reviews.all()
完整修正后的代码
models.py
from django.contrib.auth.models import AbstractUser from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class User(AbstractUser): name = models.CharField(max_length=200, null=True) email = models.EmailField(unique=True, default='') avatar = models.ImageField(null=True, default="defaultDp.jpg") location = models.CharField(max_length=200, null=True) class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') def __str__(self): return self.user.username class Review(models.Model): reviewer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='given_reviews') target_profile = models.ForeignKey(Profile, on_delete=models.SET_NULL, null=True, related_name='received_reviews') reviewmsg = models.TextField(null=True, blank=True) updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) def __str__(self): return f"{self.reviewer.username} -> {self.target_profile.user.username}: {self.reviewmsg[:20]}" # 自动为新创建的User生成Profile @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save()
views.py
from django.shortcuts import get_object_or_404, redirect, render from .models import User, Review def userProfile(request, pk): user = get_object_or_404(User, id=pk) rooms = user.room_set.all() reviews = user.profile.received_reviews.all() if request.method == 'POST': Review.objects.create( reviewer=request.user, target_profile=user.profile, reviewmsg=request.POST.get('reviewmsg') ) return redirect('user-profile', pk=user.id) context = {'user': user, 'rooms': rooms, 'reviews': reviews} return render(request, 'pages/profile.html', context)
最后要做的事
执行数据库迁移命令,让模型修改生效:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者ian
相关产品推荐
相关产品推荐

