So, right now when my DetailView subclass doesn't find an object using the PK (which is taken from the URL), I see the 404.html template page. What I'd rather do is just redirect to another URL. Here's my url patterns:
url(r'^(?P<pk>[0-9]+)/$', DeviceDetailView.as_view(
template_name='devices/detail.html',
queryset=Device.objects.all(),
context_object_name="device",
)),
url(r'^$', FullListView.as_view(template_name='devices/devices.html',)),
So, if my url looks like /devices/8/, it uses 8 as the primary key. Works great when 8 exists in the database. However, when 8 doesn't exist, it goes to the 404 page. What I would rather it do is go to a list - in fact, the FullListView listed when last url (which is what happens when the url looks like /devices/nonnumericstuff/.
Seems like that should be pretty easy, no? I don't want all 404's to go there so i can't use handler404.
For common cases
from django.http import Http404
from django.shortcuts import redirect
from django.urls import reverse
from django.views.generic import DetailView
class MyDetailView(DetailView):
def get(self, request, *args, **kwargs):
try:
return super().get(request, *args, **kwargs)
except Http404:
return redirect(reverse('my_list_view_name'))
The DetailView
's get_object
method raises an Http404
exception if the object doesn't exist in the queryset. Instead of overriding the get_object
method you could catch the exception in the view's get
method:
from django.http import Http404
from django.views.generic import DetailView
from django.shortcuts import redirect
class MyDetailView(DetailView):
def get(self, request, *args, **kwargs):
try:
self.object = self.get_object()
except Http404:
# redirect here
return redirect(url)
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With