Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Django Class-based Views Customizing Class-based Views Custom Mixin

I don't succeed to set the 'success_message'.

Hi there,

I don't succeed to set the success message, despite of the right syntaxe.

ANy ideas?

articles/views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.urlresolvers import reverse_lazy
from django.views import generic

from . import mixins
from . import models


class ArticleList(generic.ListView):
    model = models.Article


class ArticleDetail(generic.DeleteView, generic.DetailView):
    model = models.Article
    template_name = 'articles/article_detail.html'


class ArticleCreate(LoginRequiredMixin, generic.CreateView, mixins.SuccessMessageMixin):
    fields = ('title', 'body', 'author', 'published')
    model = models.Article
    success_message = "Article created!"

class ArticleUpdate(LoginRequiredMixin, generic.UpdateView, mixins.SuccessMessageMixin):
    fields = ('title', 'body', 'author', 'published')
    model = models.Article

    def get_success_message(self):
        obj = self.get_object()
        return "{} updated!".format(obj)


class ArticleDelete(LoginRequiredMixin, generic.DeleteView):
    model = models.Article
    success_url = reverse_lazy('articles:list')


class ArticleSearch(generic.ListView):
    model = models.Article

    def get_queryset(self):
        qs = super().get_queryset()
        term = self.kwargs.get('term')
        if term:
            return qs.filter(body__icontains=term)
        return qs.none()
articles/mixins.py
from django.contrib import messages

class SuccessMessageMixin:
    success_message=""

    def get_success_message(self):
        return self.success_message

    def form_valid(self, form):
        messages.success(self.request, self.get_success_message())
        return super(form).form_valid(form)

7 Answers

in your form_valid method, what happens if you just pass super() instead of super(form)?

return super().form_valid(form)  # try this
return super(form).form_valid(form)  # instead of this

might have something to do with the order (LoginRequiredMixin, generic.CreateView, mixins.SuccessMessageMixin)

I changed the order like in the video, and I add in the updateView (obj.title), however, the error still occurs.

in articles/views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.urlresolvers import reverse_lazy
from django.views import generic

from . import mixins
from . import models


class ArticleList(generic.ListView):
    model = models.Article


class ArticleDetail(generic.DeleteView, generic.DetailView):
    model = models.Article
    template_name = 'articles/article_detail.html'


class ArticleCreate(LoginRequiredMixin, mixins.SuccessMessageMixin, generic.CreateView):
    fields = ('title', 'body', 'author', 'published')
    model = models.Article
    success_message = "Article created!"


class ArticleUpdate(LoginRequiredMixin, mixins.SuccessMessageMixin, generic.UpdateView):
    fields = ('title', 'body', 'author', 'published')
    model = models.Article

    def get_success_message(self):
        obj = self.get_object()
        return "{} updated!".format(obj.title)


class ArticleDelete(LoginRequiredMixin, generic.DeleteView):
    model = models.Article
    success_url = reverse_lazy('articles:list')


class ArticleSearch(generic.ListView):
    model = models.Article

    def get_queryset(self):
        qs = super().get_queryset()
        term = self.kwargs.get('term')
        if term:
            return qs.filter(body__icontains=term)
        return qs.none()

in articles/mixins.py

from django.contrib import messages

class SuccessMessageMixin:
    success_message = ""

    def get_success_message(self):
        return self.success_message

    def form_valid(self, form):
        messages.success(self.request, self.get_success_message())
        return super(ModelFormMixin, self).form_valid(form)

The error seems to come from the ArticleView, "Hmm, didn't get the right success message from 'ArticleCreate'

try call self.object() instead of self.object().title, like this:

    def get_success_message(self):
        return "{} updated!".format(self.object())

The same error occurs with these versions:

def get_success_message(self):
        return "{} updated!".format(self.object())
def get_success_message(self):
        return "{} updated!".format(self.get_object())
def get_success_message(self):
        obj = self.get_object()
        return "{} updated!".format(obj)
def get_success_message(self):
        obj = self.object()
        return "{} updated!".format(obj)
def get_success_message(self):
        obj = self.get_object()
        return "{} updated!".format(obj.title)
def get_success_message(self):
        obj = self.object()
        return "{} updated!".format(obj.title)

Nothing works, but following the error message it comes from the 'ArticleCreate' and not the 'ArticleUpdate'

I don't know how to explain that in english, sorry :-P

But usually I just use super() because I've noticed that super(something here, self) and super() is the same (I might be wrong) - I think it's just a personal preference :-)

Hi Henrik,

Indeed, it works. in ccbv.co.uk, they wrote:

ModelFormMixin If the form is valid, save the associated model.

def form_valid(self, form): """ If the form is valid, save the associated model. """ self.object = form.save() return super(ModelFormMixin, self).form_valid(form)

How do we know if in the mixin we have to make super(form) or super(ModelFormMixin, self) or super() only?