jul
jul

Reputation: 37484

How to use DetailView to override the view of an object that does not exists?

I want to override the admin default detail view for an object to use a different template when the object does not exist, i.e.

<mydomain>/admin/<myapp>/<mymodel>/<someidthatdoesexist>/

should render the default object detail view, and

<mydomain>/admin/<myapp>/<mymodel>/<someidthatdoesNOTexist>/

should render a custom template, instead of the default 404 error.

From what I've read I should use django.views.generic.detail.DetailView, but I'm not sure how I can achieve what I want.

I tried:

<b>in urls.py</b>

    url(r'^admin/<myapp>/<mymodel>/(?P<pk>\d+)/$', views.MyModelDetailView.as_view(), name='mymodel_detail'),
    url(r'^admin/', include(admin.site.urls)),

<b>in models.py</b>

class MyModelDetailView(DetailView):

    model = MyModel

    def get(self, request, *args, **kwargs):
        try:
            self.model.objects.get(pk=kwargs['pk'])           
            return super(MyModelDetailView, self).get(request, **kwargs)
        except Http404:
            # render custom template

but I get a TemplateDoesNotExist error:

<myapp>/mymodel_detail.html

What template should I set to render the default object detail view when the object exists?

EDIT

From the example given here, no template needs to be set...

Upvotes: 1

Views: 2850

Answers (1)

miki725
miki725

Reputation: 27861

The DetailView does not raise TemplateDoesNotExist anywhere in its source code. So the only probable place where the exception is being raised is in your redirect (return redirect(url)).

By the way a very useful place to browse class-based-views code is classy views at http://ccbv.co.uk/projects/Django/1.5/django.views.generic.detail/DetailView/

As for rendering a custom template if the object does not exist, you can easily modify your get function to make that work:

class MyModelDetailView(DetailView):
    model = MyModel
    template_name = 'object_is_found.html' # <= make sure to have this

    def get(self, request, *args, **kwargs):
        try:
            self.object = self.get_object()
        except Http404:
            # return custom template
            return render(request, 'no_object.html', status=404)
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)

Upvotes: 3

Related Questions