views:

151

answers:

3

Hi there

I am building a chat application. So far I am adding chat messages with jquery $.post() and this works fine.

No I need to retrieve the latest chat message from the table and append the list on the chat page. I am new to Django, so please go slow.

So how do I get this back to the chatpage?

Thank in advance!

A: 

Since you're already using an AJAX post, why don't you return the data from that and insert it into the div? The view that accepts the post can return a rendered template or JSON, and your javascript can insert it in the callback.

Daniel Roseman
Hi there Daniel! So then I will just append() the div with the value? I need to update the div with the newest posts every x seconds..
Harry
+1  A: 

My favorite technique for this kind of thing is to use an inclusion tag

basically you make a separate template for rendering the individual objects in the page template

page template:

{% load message_tags %}    

<h3>Messages</h3>
<div class="message_list">
    {% for message in messages %}
        {% render_message message %}
    {% endfor %}
</div>

templatetags/message_tags.py:

from django import template

register = template.Library()

@register.inclusion_tag('individual_message.html')
def render_message(message):
    context_for_rendering_inclusion_tag = {'message': message}
    return context_for_rendering_inclusion_tag

now you can use the same template to render the the additional messages you want to add to the message_list div in a separate view which you can call from your ajax code

def ajax_retrieve_latest_message(request):
    # ... Get the lastest message
    render_to_response('individual_message.html', ...

And your jQuery will look something like...

$.post(url_of_ajax_view, request_data, function(data, status) {
    if (status == 'success') {
        $(".message_list").append(data);
    }
});

For completeness, your individual_message.html file would contain all the markup for displaying the actual message on the page...

Hope this all helps :)

Jiaaro
A: 

There's a lot going on in order to make this process work...

  • The client regularly polls the server for new chat entries
  • The server checks for and only replies with the newest
  • The client receives the newest entries and appends them to the DOM

This can be confusing when you're first starting because it's not always clear what the client does and what the server does, but if the large problem is broken down I think you'll find it's a simple process.

If the client is going to regularly poll the server for new chat entries, then the server (django) needs to have some type of API to do so. Your biggest decision will be what data type the server returns. You can choose from: rendered HTML, XML, YAML, or JSON. The lightest weight is JSON, and it's supported by most of the major javascript frameworks (and django includes a JSON serializer since it's that awesome).

# Your model I'm assuming is something to the effect of...
class ChatLine(models.Model):
    screenname = model.ChatField(max_length=40)
    value = models.CharField(max_length=100)
    created = models.DateTimeField(default=datetime.now())

# A url pattern to match our API...
url(r'^api/latest-chat/(?P<seconds_old>\d+)/$',get_latest_chat),

# A view to answer that URL
def get_latest_chat(request, seconds_old):
    # Query comments since the past X seconds
    chat_since = datetime.datetime.now() - datetime.timedelta(seconds=seconds_old)
    chat = Chat.objects.filter(created__gte=comments_since)

    # Return serialized data or whatever you're doing with it
    return HttpResponse(simplejson.dumps(chat),mimetype='application/json')

So whenever we poll our API, we should get back something like this..

[
    {
        'value':'Hello World',
        'created':'2009-12-10 14:56:11',
        'screenname':'tstone'
    },
    {
        'value':'And more cool Django-ness',
        'created':'2009-12-10 14:58:49',
        'screenname':'leethax0r1337'
    },
]

On our actual page, we have a <div> tag which we'll call <div id="chatbox"> which will hold whatever the incoming chat messages are. Our javascript simple needs to poll the server API that we created, check if there is a response, and then if there are items, append them to the chat box.

<!-- I'm assuming you're using jQuery -->
<script type="text/javascript">

    LATEST_CHAT_URL = '{% url get_latest_chat 5 %}';

    // On page start...
    $(function() {
        // Start a timer that will call our API at regular intervals
        // The 2nd value is the time in milliseconds, so 5000 = 5 seconds
        setTimeout(updateChat, 5000)
    });

    function updateChat() {
        $.getJSON(LATEST_CHAT_URL, function(data){
            // Enumerate JSON objects
            $.each(data.items, function(i,item){
                var newChatLine = $('<span class="chat"></span>');
                newChatLine.append('<span class="user">' + item.screenname + '</span>');
                newChatLine.append('<span class="text">' + item.text + '</span>');
                $('#chatbox').append(newChatLine);
            });
        });
    }

</script>

<div id="chatbox">
</div>

Now of course I haven't tested any of this, but I hope that gives you an idea about how the whole goes together.

T. Stone