Raising a 404 error from a Class Based View in Django

Sometimes you may wish to raise a 404 in the middle of a class based view.

Perhaps you determine in the middle of get_context_data() that you don’t want this user accessing the object for some reason.

Consider a horse stable, that has owners, stable hands, stable managers and the general public. You don’t want every person to have access to every horse.

In this case if we had a complex permission structure built on the model for determining if users could see a particular horse. It’s a simple as raising a Http404 exeption:

from django.http import Http404
from django.views.generic.detail import DetailView

class  HorseView(DetailView):
    model = Horse
    template_name = "horses/horse_view.html"

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    horse = Horse.objects.get(pk = self.kwargs['pk'])

    if not horse.is_viewable_by(self.request.user):
        raise Http404

    # continue with the rest of the method populating the context
    return context

In this case, a horse is viewable if you own the animal or you belong to a stable that has given you view access to that animal. If you are not allowed to view the animal you get a 404.

Http404 docs

And yes – maybe I need to investigate putting this into a Mixin or a decorator.

Tags:

Leave a Reply