Return 来自 CreateView 的 form_valid() 而不保存实例

Return from CreateView's form_valid() without saving an instance

在处理表单提交时,我必须执行自定义逻辑(联系网络服务等)。万一失败,我想阻止创建模型 Car 的新实例。

让我们通过一个简单的片段来演示:

from django.views import generic
from django.http import HttpResponseRedirect

class CarCreateView(generic.edit.CreateView):
      model = Car
      form_class = CarForm

      def form_valid(self, form):

           # some logic that may succeed or fail

           if success:
               messages.success(self.request, 'bla bla') 
               return super().form_valid(form)
           else:
               messages.error(self.request, 'blabla')
               # How to return to form index without saving???
               return HttpResponseRedirect(self.get_success_url())

不调用 super().form_valid(form) 是不够的。一辆新车仍在保存中。有什么想法吗?

from django.views.generic import CreateView
from django.http import HttpResponseRedirect

class CarCreateView(CreateView):
      model = Car
      form_class = CarForm

      def form_valid(self, form):

           # some logic that may succeed or fail

           if success:
               messages.success(self.request, 'bla bla') 
               return super(CarCreateView, self).form_valid(form)
           else:
               messages.error(self.request, 'blabla')
               return super(CarCreateView, self).form_invalid(form)

其实我一直都错了。愚蠢的错误。当我保存新实例时,执行从未达到那个点。

对于任何调查同一问题的人来说,处理这个问题的更简洁的方法似乎是

return self.render_to_response(self.get_context_data(form=form))

因此代码看起来像:

from django.views.generic import CreateView
from django.http import HttpResponseRedirect

class CarCreateView(CreateView):
      model = Car
      form_class = CarForm

      def form_valid(self, form):

           # some logic that may succeed or fail

           if success:
               messages.success(self.request, 'bla bla') 
               return super(CarCreateView, self).form_valid(form)
           else:
               messages.error(self.request, 'blabla')
               return self.render_to_response(self.get_context_data(form=form))

这样我们就return同一个表单页面,无需创建新实例。