Reputation: 304
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
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