[Fixed]-Django – Rendering Inclusion Tag from a View

2👍

This sounds like a job for the render_to_string or render_to_response shortcuts:
https://docs.djangoproject.com/en/dev/ref/templates/api/#the-render-to-string-shortcut
https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#django.shortcuts.render_to_response

We can still use the inclusion tag to generate a template context dict from our args (as helpfully pointed out by @BobStein-VisiBone in comments)

from django.template.loader import render_to_string
from django.shortcuts import render_to_response

from .templatetags import my_inclusion_tag


rendered = render_to_string('my_include.html', my_inclusion_tag(foo='bar'))

#or

def my_view(request):
    if request.is_ajax():
        return render_to_response('my_include.html',
                      my_inclusion_tag(foo='bar'),
                      context_instance=RequestContext(request))

1👍

quick and dirty way could be to have a view, that renders a template, that only contains your templatetag.

👤sjh

1👍

I was trying to do the exact same thing today, and ended up writing a helper function to render template tags:

def render_templatetag(request, tag_string, tag_file, dictionary=None):
    dictionary = dictionary or {}
    context_instance = RequestContext(request)
    context_instance.update(dictionary)
    t = Template("{%% load %s %%}{%% %s %%}" % (tag_file, tag_string))
    return t.render(context_instance)

tag_string is the call to the template tag as it’d appear in a normal template, and tag_file is the file you need to load for the template tag.

👤Eric

0👍

This is certainly possible. A view can render any template that an inclusion tag can. The advantage of this approach is that you can leverage the full strength of Django’s templates.

On the other hand AJAX responses typically do not contain HTML so much as XML/JSON. If you are using Django’s template features you are better off with returning HTML. If not, XML/JSON might make more sense. Just my two cents.

0👍

Using inclusion tag with configurable template decorator provided by Gonz instead of default Django’s inclusion tags you can write a helper in your view:

from django.template.loader import render_to_string
from home.templatetags.objectwidgets import object_widget

def _object_widget(request, obj):
    template, context = object_widget(RequestContext(request), obj)
    return render_to_string(template, context)

It’s DRY and works with Django 1.3 (I haven’t tested it with Django 1.4).

I use this technique to return search results rendered in HTML via JSON/AJAX calls (nothing better which I came up with).

0👍

It’s possible, but probably bit hacky, complex or complicated.

What I would suggest, is architect it so that you have the rendering part in utils.py function and use it in a simple_tag instead of an inclusion_tag. This way you can then use the same utils rendering function easily in views.

In my (very simplified) imaginary example I have listing of users and a “Load more” button that returns more users.

account/utils.py

from django.template.loader import render_to_string


def render_users(users):
    return render_to_string("account/user_list_items.html", {"users": users})

account/templatetags/account_tags.py

from django import template

from ..utils import render_users

register = template.Library()


@register.simple_tag
def list_users(users):
    return render_users(users)

account/views.py

from django.http import HttpResponse

from .models import User
from .utils import render_users


def load_more_users(request):
    limit = request.GET["limit"]
    offset = request.GET["offset"]
    users = User.objects.all()[offset:offset + limit]
    return HttpResponse(render_users(users))

Simple is better than complex.

Leave a comment