Skip to content

Doing ajax with django admin

Problem

Some times we want to make an ajax request to django admin default views But you cannot override templates and return data in the format you need.

Idea

  • we don't want to rewrite django admin code
  • we don't want to copy/paste any existing functions so we don't break compatability with new django version
  • we prefer to write as little code as possible

Solution

We can easily replace view template. and return data in a format we need

  1. Create new TemplateResponse class which will check if its an ajax request then change template file. Example, update history template for ajax request:
python
if 'x-requested-with' in request.headers and \
  request.headers['x-requested-with'] == 'XMLHttpRequest':
  # handle object history request correctly
  if "admin/object_history.html" in template:
      template = ["admin/ajax/object_history.html"] + template

Full example

python
from django.template.response import SimpleTemplateResponse, TemplateResponse


class AjaxTemplateResponse(TemplateResponse):
    rendering_attrs = SimpleTemplateResponse.rendering_attrs + ["_request"]

    def __init__(
        self,
        request,
        template,
        context=None,
        content_type=None,
        status=None,
        charset=None,
        using=None,
        headers=None,
    ):
        if 'x-requested-with' in request.headers and \
            request.headers['x-requested-with'] == 'XMLHttpRequest':
            # handle object history request correctly
            if "admin/object_history.html" in template:
                template = ["admin/ajax/object_history.html"] + template
        super(TemplateResponse, self).__init__(
            template, context, content_type, status, charset, using, headers=headers
        )
        self._request = request

TemplateResponse.__init__ = AjaxTemplateResponse.__init__