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
- Create new
TemplateResponse
class which will check if its an ajax request then change template file. Example, update history template for ajax request:
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
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__