Django UpdateView未更新实例反而创建新实例问题求助
排查Django UpdateView创建新实例的问题
嘿,我来帮你捋捋这个问题!你用UpdateView更新Question模型却创建了新实例,在Django 1.11里大概率是这几个常见原因导致的,咱们一个个排查:
URL没传递主键参数
UpdateView必须知道要更新哪条记录,所以你的URL配置里必须包含pk(或slug)参数。举个正确的URL配置例子:url(r'^question/(?P<pk>\d+)/update/$', QuestionUpdate.as_view(), name='question_update'),如果访问更新页面时URL里没有类似
/question/3/update/这样的数字主键,UpdateView找不到目标对象,就会默认走创建新实例的逻辑。重写视图方法时弄丢了instance
如果你在QuestionUpdate里重写了get_form或form_valid方法,不小心没给表单传入要更新的对象实例,就会触发新建操作。比如重写get_form时要确保传入instance:def get_form(self, form_class=None): form = super().get_form(form_class) form.instance = self.get_object() return form当然,默认的UpdateView会自动处理instance绑定,除非你自己修改了这部分逻辑。
模型或视图的对象查找逻辑有问题
- 检查下Question模型有没有自定义主键?如果用了非默认的
id作为主键,得在视图里指定pk_url_kwarg来匹配URL里的参数,或者重写get_object方法明确查找规则:class QuestionUpdate(generic.UpdateView): model = models.Question form_class = QuestionForm pk_url_kwarg = 'question_id' # 如果URL里用的是question_id而不是pk def get_object(self): return models.Question.objects.get(pk=self.kwargs.get('question_id')) - 另外,要是你在模型的
save方法里写了self.pk = None这类代码,保存时就会强制创建新实例,得把这行删掉。
- 检查下Question模型有没有自定义主键?如果用了非默认的
form_valid方法重写出错
如果你重写了form_valid,一定要确保把表单保存的对象赋值给self.object,不然UpdateView会误以为是新创建的对象:def form_valid(self, form): self.object = form.save() return super().form_valid(form)
你可以先从URL配置查起,这是最容易踩坑的地方。也可以在视图里加个打印语句,看看self.get_object()能不能正确获取到要更新的Question对象——如果获取不到,那就是对象查找的问题啦。
内容的提问来源于stack exchange,提问作者Cflux
相关产品推荐
相关产品推荐

