2

The project I'm working on has some data that needs to get passed to every view, so we have a wrapper around render_to_response called master_rtr. Ok.

Now, I need our 404 pages to run through this as well. Per the instructions, I created a custom 404 handler (cleverly called custom_404) that calls master_rtr. Everything looks good, but our tests are failing, because we're receiving back a 200 OK.

So, I'm trying to figure out how to return a 404 status code, instead. There seems to be an HttpResponseNotFound class that's kinda what I want, but I'm not quite sure how to construct all of that nonsense instead of using render_to_response. Or rather, I could probably figure it out, but it seems like their must be an easier way; is there?

The appropriate parts of the code:

 def master_rtr(request, template, data = {}): if request.user.is_authenticated(): # Since we're only grabbing the enrollments to get at the courses, # doing select_related() will save us from having to hit database for # every course the user is enrolled in data['courses'] = \ [e.course for e in \ Enrollment.objects.select_related().filter(user=request.user) \ if e.view] else: if "anonCourses" in request.session: data['courses'] = request.session['anonCourses'] else: data['courses'] = [] data['THEME'] = settings.THEME return render_to_response(template, data, context_instance=RequestContext(request)) def custom_404(request): response = master_rtr(request, '404.html') response.status_code = 404 return response 

3 Answers 3

10

The easy way:

def custom_404(request): response = master_rtr(...) response.status_code = 404 return response 

But I have to ask: why aren't you just using a context processor along with a RequestContext to pass the data to the views?

Sign up to request clarification or add additional context in comments.

2 Comments

Ah yes, that's what I was looking for. Updated the question with code.
Well it definitely looks like you could just be doing that in a context processor (and then adding it to the TEMPLATE_CONTEXT_PROCESSORS setting). If you're worried about losing the simpler shortcut which uses RequestContext, you can just use django.views.generic.simple.direct_to_template
1

Just set status_code on the response.

Comments

1

Into your application's views.py add:

# Imports from django.shortcuts import render from django.http import HttpResponse from django.template import Context, loader ## # Handle 404 Errors # @param request WSGIRequest list with all HTTP Request def error404(request): # 1. Load models for this view #from idgsupply.models import My404Method # 2. Generate Content for this view template = loader.get_template('404.htm') context = Context({ 'message': 'All: %s' % request, }) # 3. Return Template for this view + Data return HttpResponse(content=template.render(context), content_type='text/html; charset=utf-8', status=404) 

The secret is in the last line: status=404

Hope it helped!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.