Efaz
Efaz

Reputation: 304

Adding Ajax to Django

I have a simple messaging system built in my Django project. Currently, a user needs to refresh the page to see the new messages. How do I add Ajax to load the messages asynchronously?

View:

def user_messages(request):
    time_now = datetime.datetime.now()
    user = request.user

    if request.method == "POST":
        sender = request.user
        receiver_name = request.POST.get('msg_receiver')
        receiver = User.objects.get(username=receiver_name)
        msg_content = request.POST.get('msg_content')

        Messages.objects.create(sender=sender, receiver=receiver, msg_content=msg_content)

    inbox = Messages.objects.filter(receiver=user).order_by('-timestamp')
    outbox = Messages.objects.filter(sender=user).order_by('-timestamp')

    context = {'inbox': inbox, 'outbox': outbox, 'time_now': time_now}

    return render(request, 'accounts/messages.html', context)

Messages.html:

<h6>Inbox</h6>
        {% for message in inbox %}
            <ul>
                <li title="{{ message.sender.username }}">{{ message.sender.first_name }}: {{ message.msg_content }}
                    <button onclick="myFunction()">Reply</button>
                </li>
                <small>-{{ message.timestamp }}</small>
                <hr>
            </ul>
        {% endfor %}

Upvotes: 0

Views: 125

Answers (1)

Eduardo Matsuoka
Eduardo Matsuoka

Reputation: 716

You can create a Javascript file in the static folder to do this.

As you are sending a POST request, you need to include the CSRF token in order to do this process in a secure manner. Check on Django's documentation for more details. This first function get the CSRF token from the cookies:

getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        let cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            let cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

This is the Ajax code for sending/receiving data, just vanilla Javascript. The same code would load the previous messages when the user loads the page for the first time, after x seconds (to display messages if someone else sends a message) or after the user sends a message:

requestAjax(data) {
    // Gets the CSRF token using the previous function
    let csrftoken = getCookie('csrftoken');

    // Initiate new AJAX request
    const request = new XMLHttpRequest();
    request.open('POST', '/add-messages/', true);

    // Set request header with CSRF token code
    request.setRequestHeader('X-CSRFToken', csrftoken);
    request.setRequestHeader('contentType', 'application/json; charset=utf-8');

    // Callback function for when the request completes
    request.onload = () => {
        // The server returns a request object
        const serverResponse = JSON.parse(request.responseText);
        
        // The request object includes a 'success' key with a boolean value to indicate if the request was successful or not
        if (serverResponse.success) {
            // If 'success' is true, display the received messages
        }
        else {
            // If 'success' is false, there is a server side error, display error message
        }
    }

    // Sends msg_receiver and msg_content to server
    request.send(JSON.stringify(data));
}

Upvotes: 2

Related Questions