Django中如何获取特定登录用户关联的Answer模型数据
解决Django中获取当前登录用户对应答案的问题
看起来你已经搭好了基础模型,但在获取用户专属答案时踩了两个常见小坑:一是answer_set是关联该问题的所有答案集合,不是单个对象,直接访问.answer肯定拿不到数据;二是没有过滤当前登录用户的答案,系统不知道你要取哪个用户的内容。下面给你几个清晰的解决方案,从优化到实现一步步来:
第一步:给模型加唯一约束(可选但强烈推荐)
为了避免同一个用户对同一个问题提交多个答案,给Answer模型添加联合唯一约束,保证数据一致性:
class Answer(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) answer = models.TextField(max_length=600, null=True, blank=True, default=" ") edit_date = models.DateTimeField(auto_now_add=True) class Meta: # 强制一个用户对一个问题只能有一个答案 unique_together = ('question', 'user') def __str__(self): return self.answer
第二步:优化视图,预取用户答案(推荐生产方案)
在视图里把当前用户的答案和问题关联起来,还能避免Django常见的N+1查询性能问题:
from django.contrib.auth.decorators import login_required from django.db.models import Prefetch # 确保只有登录用户能访问,加login_required装饰器 @login_required def InterviewQuestion(request): # 筛选当前用户的所有答案 user_answers = Answer.objects.filter(user=request.user) # 预取答案并关联到对应问题,存到user_answer属性中 questions = Question.objects.all().prefetch_related( Prefetch('answer_set', queryset=user_answers, to_attr='user_answer') ) context = {'questions': questions} return render(request, 'jobs/ace-interview.html', context)
第三步:修改模板,显示用户专属答案
现在每个question对象都有了user_answer属性(仅包含当前用户的答案集合),我们取第一个即可(因为加了唯一约束,最多只有一个):
{% for question in questions %} <div class="card"> <div class="card-body"> <h5 class="card-title">{{question.question}}</h5> {% with user_answer=question.user_answer.first %} <p class="card-text">{{ user_answer.answer|default:"还未作答" }}</p> {% endwith %} </div> </div> {% endfor %}
用|default过滤器处理用户未作答的情况,避免模板报错。
替代方案:直接在模板中过滤(适合快速测试)
如果只是想快速验证效果,也可以直接在模板里过滤当前用户的答案,但这种方式在问题较多时会有性能损耗,不推荐生产环境使用:
{% for question in questions %} <div class="card"> <div class="card-body"> <h5 class="card-title">{{question.question}}</h5> {% with answer=question.answer_set.filter(user=request.user).first %} <p class="card-text">{{ answer.answer|default:"还未作答" }}</p> {% endwith %} </div> </div> {% endfor %}
最后提醒:一定要给视图加上@login_required,确保只有登录用户能访问这个页面,不然request.user会是匿名用户,永远拿不到答案哦!
内容的提问来源于stack exchange,提问作者Syed
相关产品推荐
相关产品推荐

