Django view helper for handling different URL extensions

I often find that I would like to provide different responses using the same view function, based on the URL extension. So, ‘.html’ returns an HTML web page, ‘.xml’ returns an XML document, ‘.json’ returns a JSON data structure, etc. — without having to write special views for each response type or repeat type detection code.  So, here’s what I’ve come up with as a helper function:

import re
from mimetypes import guess_type

def get_type_and_extension(request, type_if_noext=None, type_if_none='application/octet-stream'):
    mimetype, extension = type_if_noext, None
    pattern = '\.\w+$'
    m = re.search(pattern, request.path)
    if m is not None:
        mimetype = guess_type(request.path)[0] or type_if_none
        extension = m.group(0)
    return mimetype, extension

An example URL pattern:

(r'^jobs/(?P<job_id>\d+)/report(\.html|\.xml|/)$', 'job_report')

This patterns supports the URLs:

jobs/[job_id]/report.html
jobs/[job_id]/report.xml
jobs/[job_id]/report/

A more general pattern might look like:

(r'^jobs/(?P<job_id>\d+)/report(\.\w+|/)$', 'job_report')

An example view:

from mimetypes import types_map
from django import http

def job_report(request, job_id):
    job = get_job(job_id) # pretend this does something
    # the default report format is XML, so set the default
    mimetype, extension = get_type_and_extension(request, type_if_noext=types_map['.xml'])
    # job.report() returns content based on extension
    return http.HttpResponse(job.report(extension or ''), mimetype=mimetype)

That’s what I’ve got so far. Comments welcome.

Advertisements

,