Django重载UpdateView的post方法自动填充字段无效问题
问题原因
你这段代码里的修改不生效,核心原因是UpdateView的post方法执行流程会覆盖你手动修改的对象:
- 你在post方法开头修改了
self.object.is_active = False,但调用super().post()后,父类会重新从请求中构建表单、验证数据,最终调用表单的save()方法保存对象——这个过程会使用表单数据重新更新对象,完全忽略你之前手动修改的字段值。 - 而且你修改
self.object后并没有手动保存,父类的流程也不会基于你修改后的对象去处理,所以你的修改根本不会被持久化到数据库。
正确实现方式
推荐用Django类视图提供的钩子方法来实现,以下是两种靠谱的方案:
方案一:重写form_valid方法(最推荐)
form_valid是表单验证通过后、保存对象前的钩子,在这里修改对象字段会被正确保存:
class ProfileView(generic.UpdateView): model = User fields = [...] template_name_suffix = '_update_form' success_url = reverse_lazy('home') def form_valid(self, form): # 在表单保存前,修改目标字段 form.instance.is_active = False # 调用父类方法完成保存和跳转 return super().form_valid(form)
方案二:自定义ModelForm并重写save方法
如果需要更复杂的字段处理逻辑,可以自定义表单:
from django import forms from django.contrib.auth.models import User class UserProfileForm(forms.ModelForm): class Meta: model = User fields = [...] # 和视图里的字段保持一致 def save(self, commit=True): # 先获取未保存的实例 instance = super().save(commit=False) # 修改字段 instance.is_active = False # 如果需要立即保存,执行save if commit: instance.save() return instance # 视图中指定自定义表单 class ProfileView(generic.UpdateView): model = User form_class = UserProfileForm template_name_suffix = '_update_form' success_url = reverse_lazy('home')
不推荐的方案(仅作参考)
如果一定要在post方法里处理,需要确保修改在父类保存之后,但这种方式容易出现逻辑漏洞(比如表单验证失败时也会修改字段):
def post(self, request, *args, **kwargs): # 先让父类完成表单处理和对象保存 response = super().post(request, *args, **kwargs) # 重新修改并保存对象 self.object.is_active = False self.object.save() return response
内容的提问来源于stack exchange,提问作者Octavian Niculescu
相关产品推荐
相关产品推荐

