Django中如何将用户当前积分设为任务积分并解决查询多对象错误?
解决方案
一、修复查询语句(传入当前用户ID)
你的查询报错是因为没有过滤当前登录用户,导致PointsforUser.objects.filter(...)返回了所有用户的积分记录,而非当前用户的单条记录。正确写法如下:
1. 基础写法(Task的points为IntegerField时)
# 获取当前登录用户的积分记录 user_points = PointsforUser.objects.get(user=self.request.user) # 过滤出任务积分小于用户当前积分的任务 tasks = Task.objects.filter(points__lt=user_points.points)
2. 适配Task的points为CharField的情况
你的Task模型中points是CharField,直接用数值比较会出错,要么把字段改成IntegerField:
class Task(models.Model): # ... 其他字段 points = models.IntegerField(null=True, default=1) # 替换原CharField
要么用Cast转换类型后比较:
from django.db.models import Cast, IntegerField user_points = PointsforUser.objects.get(user=self.request.user) tasks = Task.objects.filter( Cast('points', IntegerField())__lt=user_points.points )
二、创建RunningTasks时设置用户当前积分
在RunTaskCreateUserView中重写form_valid方法,在保存表单前完成字段赋值:
class RunTaskCreateUserView(LoginRequiredMixin, CreateView): model = RunningTasks template_name = 'usersboard/tasks_create.html' form_class = TaskCreateForm def form_valid(self, form): # 关联当前登录用户 form.instance.user = self.request.user # 获取当前用户的积分余额(用get_or_create避免用户无积分记录的报错) user_points_obj, _ = PointsforUser.objects.get_or_create( user=self.request.user, defaults={'points': 0} ) # 将用户积分赋值给RunningTasks的points字段 form.instance.points = user_points_obj.points # 调用父类方法保存表单 return super().form_valid(form)
额外优化建议
- 你的
RunningTasks模型中user字段设置了null=True, blank=True,但登录用户创建任务时必然关联用户,建议去掉这两个参数,强制关联:class RunningTasks(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) # ... 其他字段
内容的提问来源于stack exchange,提问作者kkk
相关产品推荐
相关产品推荐

