Django中通过EventDetailView修改Event模型free_places字段无效求助
嘿,我帮你找出问题啦!
首先看你代码里的这行:self.object.free_places - 1——这行只是算了个减法,但根本没把结果存回free_places字段里啊!就像你算完数没把答案写回本子上,数据库当然不会变啦😅
先解决最核心的生效问题
把那行代码改成赋值操作就行:
def post(self, request, *args, **kwargs): form = self.get_form() if form.is_valid(): self.object = self.get_object() # 重点!要把减1后的值赋值回去 self.object.free_places -= 1 self.object.save() return self.form_valid(form) else: return self.form_invalid(form)
进阶优化:避免多人同时订阅的计数错误
如果你的活动可能有很多人同时报名,直接这么改可能会有小bug——比如两个用户同时提交,free_places可能只减了1而不是2。这时候用Django的F()表达式就很靠谱,它会让数据库直接处理减法,保证操作是原子性的:
# 记得先导入F from django.db.models import F def post(self, request, *args, **kwargs): form = self.get_form() if form.is_valid(): self.object = self.get_object() # 用F表达式让数据库做原子更新 self.object.free_places = F('free_places') - 1 self.object.save() # 刷新一下对象,确保后续用的是最新值 self.object.refresh_from_db() return self.form_valid(form) else: return self.form_invalid(form)
更贴合Django规范的写法
因为你继承了ModelFormMixin,其实把更新逻辑放到form_valid方法里会更清晰,符合Django视图的设计逻辑:
from django.db.models import F class EventDetailView(DetailView, ModelFormMixin): model = models.Event form_class = forms.RegisterForm context_object_name = 'event' def get_success_url(self): return reverse('events:list') def get_initial(self): return {'event': self.kwargs['pk']} # 先获取当前Event对象,再调用父类的post方法 def post(self, request, *args, **kwargs): self.object = self.get_object() return super().post(request, *args, **kwargs) def form_valid(self, form): # 先更新剩余名额 self.object.free_places = F('free_places') - 1 self.object.save() self.object.refresh_from_db() # 再保存用户的注册信息 return super().form_valid(form)
这样改完,用户提交表单验证通过后,free_places就会稳稳地减1啦~
内容的提问来源于stack exchange,提问作者user9192656
相关产品推荐
相关产品推荐

