Search code examples
pythondjangodjango-formsdjango-views

Django - CreateView - Send a custom Error Message if model form is not valid


I have some Class Based Views where I use the Django messages framework to send a success_message if the form POST is_valid.

I would also like to send a custom error_message if the form POST is not valid.

It was very obvious how to configure the success_message, just use the SuccessMessageMixin and add a "success_message" variable. I have tried the same approach for an error_message, but none one of my attempts showed the error flash message on the form page - my attempts are commented out below in the else: block.

Sending an error message to a CBV seems like something that would be a pretty common scenario, yet I cannot find any examples in the Django docs or anywhere else online.

Does anyone know how I can get this done?

Just to be clear - I am not talking about adding ValidationErrors that are created for specific fields. I have ValidationErrors for fields working fine. This refers to a custom flash message that would be present at the top of the page.

#views.py

class DocCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView): 
    model = Doc
    form_class = DocForm
    template_name = "doc/doc_form.html"
    context_object_name = 'doc'
    success_message = 'Doc successfully created!'
    error_meesage = "Error saving the Doc, check fields below."
    

    def form_valid(self, form):
        form.instance.created_by = self.request.user
        return super().form_valid(form)

    def form_submit(self, request):
        if request.method == 'POST':
            form = DocForm(request.POST)
            if form.is_valid():
                form.save()
            return HttpResponseRedirect(reverse('doc-detail'))
        else:
            # messages.error(self.request, error_message)
            # messages.add_message(self.request, messages.ERROR, error_message)
            # form = DocForm()
    
        return redirect('doc-detail', pk=post.pk)

#base.html

      {% if messages %}
          {% for message in messages %}
              <div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %}">
             {{ message }}<button type="button" class="close" data-dismiss="alert" aria-label="Close">
             <span aria-hidden="true">&times;</span></button></div>
          {% endfor %}
      {% endif %}

      {% block content %}
      {% endblock content %}

Solution

  • You can override the form_invalid(…) method [Django-doc] to add an error message:

    from django.contrib import messages
    
    class DocCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView): 
        model = Doc
        form_class = DocForm
        template_name = "doc/doc_form.html"
        context_object_name = 'doc'
        success_message = 'Doc successfully created!'
        error_message = 'Error saving the Doc, check fields below.'
        
        def get_success_url(self):
            return reverse('doc-detail', kwargs={'pk': self.object.pk})
    
        def form_valid(self, form):
            form.instance.created_by = self.request.user
            return super().form_valid(form)
    
        def form_invalid(self, form):
            messages.error(self.request, self.error_message)
            return super().form_invalid(form)