Search code examples
djangodjango-generic-views

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


While handling a form submission, I have to perform custom logic (contact web service etc). In case of failure I want to prevent the creation of a new instance of model Car.

Let's demonstrate through a simple snippet:

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())

Not calling super().form_valid(form) is not enough. A new Car is still being saved. Any ideas?


Solution

  • Actually I was wrong all along. Silly mistake. The execution never reached that point when I got the new instance saved.

    For anyone looking into the same issue, the cleaner way to handle this seems to be

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

    Thus the code would look like:

    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))
    

    That way we return the same form page, without creating a new instance.