如何在Django CreateView中使用update_or_create?更新时重复创建对象
问题根源
你当前的代码会创建重复对象,是因为form_valid里做了两件冲突的事:
- 调用
update_or_create处理目标对象 - 又调用了
super().form_valid(form),而CreateView的默认逻辑会执行form.save()再创建一个新对象
两者叠加就导致了重复创建。
修正后的代码
class CardexCreateView(LoginRequiredMixin, CreateView): model = Cardex fields = '__all__' template_name = 'cardex_add.html' def get_success_url(self): return reverse('cardexes-list') def form_valid(self, form): # 从表单获取匹配用的唯一标识(这里用product,根据你的业务规则调整) product = form.cleaned_data['product'] # 用表单提交的数据作为更新/创建的字段值 form_data = form.cleaned_data # 执行update_or_create:匹配到对应对象就更新,没匹配到就创建新对象 self.object, _ = Cardex.objects.update_or_create( product=product, defaults=form_data ) # 直接重定向,跳过父类的默认创建逻辑 return HttpResponseRedirect(self.get_success_url())
核心要点
- 必须跳过父类的
form_valid,因为它的唯一作用是创建新对象,和我们要实现的update_or_create逻辑完全冲突。 update_or_create的第一个参数是匹配条件,必须是能唯一定位对象的字段(比如你的业务规则里,一个product对应一个Cardex),否则会出现匹配错误。- 如果不需要使用表单的所有字段,可以手动构造
defaults,比如defaults={'standard_weight': form.cleaned_data['standard_weight']}。
内容的提问来源于stack exchange,提问作者MohamadHossein
相关产品推荐
相关产品推荐

