stelios
stelios

Reputation: 2855

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?

Upvotes: 1

Views: 3175

Answers (2)

stelios
stelios

Reputation: 2855

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.

Upvotes: 5

Neeraj Kumar
Neeraj Kumar

Reputation: 3951

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)

Upvotes: 1

Related Questions