Django form: ask for confirmation before committing to db

Solution

Having solved this with the help of the ideas posted here as answers, in particular those by Alexander Larikov and Chris Lawlor, I would like to post my final solution so others might benefit from it.

It turns out that it is possible to do this with CBV, and I rather like it. (Because I am a fan of keeping everything OOP) I have also made the forms as generic as possible.

First, I have made the following forms:

class BaseConfirmModelForm(BaseModelForm):
    force = forms.BooleanField(required=False, initial=0)

    def clean_force(self):
        data = self.cleaned_data['force']
        if data:
            return data
        else:
            raise forms.ValidationError('Please confirm that this {} is unique.'.format(ContentType.objects.get_for_model(self.Meta.model)))

class TvshowModelForm(BaseModelForm):            
    class Meta(BaseModelForm.Meta):
        model = Tvshow
        exclude = ('user')

"""
To ask for user confirmation in case of duplicate title
"""
class ConfirmTvshowModelForm(TvshowModelForm, BaseConfirmModelForm):
    pass   

And now making suitable views. The key here was the discovery of get_form_class as opposed to using the form_class variable.

class EditTvshowView(FormView):       
    def dispatch(self, request, *args, **kwargs):
        try:
            dup_list = get_object_duplicates(self.model, title = request.POST['title'])  
            if dup_list:         
                self.duplicate = True
                messages.add_message(request, messages.ERROR, 'Please confirm that this show is unique.')
            else:
                self.duplicate = False
        except KeyError:
            self.duplicate = False
        return super(EditTvshowView, self).dispatch(request, *args, **kwargs)

    def get_form_class(self):
        return ConfirmTvshowModelForm if self.duplicate else TvshowModelForm

"""
Classes to create and update tvshow objects.
"""
class CreateTvshowView(CreateView, EditTvshowView):  
    pass

class UpdateTvshowView(EditTvshowView, UpdateObjectView):
    model = Tvshow  

I hope this will benefit others with similar problems.


I will post it as an answer. In your form's clean method you can validate user's data in the way you want. It might look like that:

def clean(self):
    # check if 'force' checkbox is not set on the form
    if not self.cleaned_data.get('force'):
        dup_list = get_object_duplicates(Tvshow, title = self.object.title)
        if dup_list:
            raise forms.ValidationError("A tv show with this name already exists. "
                                        "Are you sure this is not the same one? "
                                        "Click submit again once you're sure this "
                                        "is new content")