views:

87

answers:

5

In some of the code I'm working on, the author max AJAX calls to a Django view that returns JSON.

Once the JSON is retrieved, it'll be injected into the page with a function that looks like this (note, this is a simplification, but I'm sure you know what I'm getting at here):

function build_event_listing(events) {
    var html = '';

    for(int i = 0; i < events.length; i++) {
        event = events[i];

        html += "<h2>" + event.title + "</h2>\n";
        html += "<p>" + event.description + "</p>";
        html += "Click <a href='/event/view/" + event.id + "'>here<a> for more info.";

    }

    events_div.html(html);
}

I really don't like this approach. To change the look of each event listing, the designer would have to modify that ugly JS. I'd much rather make use of Django's templating system, but I'm wondering how I can do this?

I had the idea of writing the view like this:

def view_listings(req):
    events = models.Event.objects.all()

    html = []
    for event in events:
        html.append(
            render_to_string('event/single_event.html', {
                'event': event,
            }, context_instance=RequestContext(req))

    return HttpResponse(''.join(html), mimetype='text/html')

... but it just seems like there should be a better way.

Any ideas?

A: 

Why not use the for loop capabilities of django's templating language?

{% for event in events %}
...
{% endfor %}

and you call it via:

render_to_string('event/events_template.html', {'events':events}, context_instance=RequestContext(req)
Olivier
That's not really the point. It's just me, not wanting to build HTML with javascript, but still wanting to return JSON via the AJAX call.
synic
A: 

I could use a modified version of tempest: http://plugins.jquery.com/project/tempest

Modified to use [[ ]] and [% %], instead of {{ }} and {% %}, because the django templating system will consume those.

synic
+1  A: 

An Ajax call can just as,easily return rendered HTML, which your Javascript can simply inject into the page. So use the tempting system to render that HTML fragment, then return it to your JS.

Daniel Roseman
What if you need to populate two divs with the data returned from one ajax query? Make two ajax calls and two database hits? Seems kind of a waste.
synic
+1  A: 

I wrote a Django/Ajax library that organises this for you. You write your template as such:

{% load ajax %}
{% adjax_include "event/_event_list.html" %}

In your view you would do something like:

import adjax

@adjax_response
def view_listings(req):
    events = models.Event.objects.all()
    adjax.render_to_response("event/_event_list.html", {'events': events})

There is also a template tag that flags a single value for replacement, eg {% adjax event.title %} and then adjax.update(request, event, ('title', 'description', 'id')) in the view. But this is only single objects currently, not query sets. It's a good idea though, I might quickly implement it.

See http://adjax.hardysoftware.com.au/how/

Will Hardy
Getting an error 500 on that link...
synic
Shared hosting :-(
Will Hardy
+1  A: 

Take a look at the jquery-haml project. It uses a variation on the very nice, compact Haml and is designed specifically for situations like yours.

Sidnicious