Login

View decorator to convert DoesNotExist (ObjectDoesNotExist) exceptions into Http404 exceptions

Author:
jammycakes
Posted:
September 26, 2009
Language:
Python
Version:
1.1
Score:
1 (after 5 ratings)

A decorator that can be applied to your views to turn ObjectDoesNotExist exceptions into Http404 exceptions. This means people will see a "Page not found" error rather than an "Internal Server Error" when they are request something that does not exist in the database.

Example:

@raise_404
def show_event(request, id):
    event = Event.objects.get(id)
    return render_to_response('events/show_event.html', { 'event' : event })
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def raise_404(method):

	def wrap(*args, **kwargs):
		from django.core.exceptions import ObjectDoesNotExist
		from django.http import Http404
		try:
			return method(*args, **kwargs)
		except ObjectDoesNotExist, ex:
			raise Http404(ex.message)

	return wrap

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 1 week ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

mbi (on September 26, 2009):

Pretty neat idea. This also works as a middleware:

from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404

class DoesNotExistTo404Middleware(object):
    def process_exception(self, request, exception):
        if isinstance(exception,ObjectDoesNotExist):
            raise Http404(exception.message)

#

jammycakes (on September 26, 2009):

The only thing to note with middleware is that if you raise Http404 exceptions at the middleware level, no subsequent processing will take place. This means that you should put the DoesNotExistTo404Middleware as the first item in your MIDDLEWARE_CLASSES setting.

It also means, for example, that if you're using separate middleware to log 404 Not Found errors, it won't pick up on any that are generated this way.

#

gregb (on September 26, 2009):

Surely get_object_or_404() would be a better way of acheiving this? It's a clever idea, but masking a server error as a 404 is bound to confuse someone who's trying to get their head around the code.

#

jammycakes (on October 3, 2009):

Indeed, get_object_or_404 is another alternative. However there are occasions when this is not appropriate.

For example, if you are raising the ObjectNotFoundException further down the call stack (e.g. in your model managers) it may be raised both within a view (when it is appropriate to turn this exception into a 404) or within a manage.py command (when it isn't).

Note also that this only turns ObjectNotFoundException into a 404 -- other types of exceptions will remain unchanged and will result in 500 Internal Server Error, as they should.

The ideal approach would obviously be to code it as middleware, as @mbi suggested, but as I have noted, there are other problems with that approach.

#

jerry2801 (on October 19, 2009):

is good way for raise 404~

#

Please login first before commenting.