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.
And yes – maybe I need to investigate putting this into a Mixin or a decorator.