Django中如何修改CustomUser模型activity_point字段?两种尝试均失败
问题分析与修复方案
第一种方法(评论增加积分)的问题
你修改了self.request.user.activity_point但没有保存用户对象,数据库中的积分不会同步更新。
修复后的代码:
class NewsDetailView(generic.DetailView): model = News template_name = 'news/news_details.html' def get_context_data(self, **kwargs): context = super().get_context_data() if self.request.user.is_authenticated: context['comment_form'] = CommentForm() return context def post(self, request, *args, **kwargs): form = CommentForm(request.POST) if form.is_valid(): news = self.get_object() form.instance.author = request.user form.instance.news = news # 修改积分并保存用户 request.user.activity_point += 5 request.user.save() # 新增保存操作 form.save() return redirect(reverse('news_detail', kwargs={ 'pk': news.uid }))
第二种方法(发布新闻增加积分)的问题
get_queryset方法的作用是返回视图要处理的查询集,在这里修改积分属于逻辑误用。CustomUser.objects.filter(...)返回的是查询集(QuerySet),不是单个用户实例,无法直接访问activity_point属性。- 积分修改逻辑应该放在
form_valid方法中——这是表单验证通过、数据即将保存的正确时机。
修复后的代码:
class CitizenNewsCreateView(mixins.LoginRequiredMixin, generic.CreateView): model = News template_name = 'news/news_create.html' form_class = CitizenReporterForm success_url = reverse_lazy('citizen_report_list') def form_valid(self, form): form.instance.author = self.request.user form.instance.active = False form.instance.citizen = True # 在表单验证通过后修改并保存积分 self.request.user.activity_point += 5 self.request.user.save() return super(CitizenNewsCreateView, self).form_valid(form)
额外优化建议
如果担心并发场景下的积分计算错误(比如同一用户同时触发两次积分操作),可以使用Django的F()表达式实现原子更新:
from django.db.models import F # 替换原积分修改代码 CustomUser.objects.filter(id=self.request.user.id).update(activity_point=F('activity_point') + 5)
这种方式直接在数据库层面执行原子操作,避免并发冲突。
内容的提问来源于stack exchange,提问作者7Berlin
相关产品推荐
相关产品推荐

