I use Ajax to update a list of objects, let's say each time a button is clicked. But I want to use Django template tags to generate each item of the list. The problem is that I have to send a JsonResponse
back to JavaScript, but there, I can't use these tags.
I have to send object attributes as json. and I'm stuck with plain html in Ajax:
...
success: function (json) {
if (json.new_messages.length) {
for (let m of json.new_messages) {
$('#messages-list').append("<li>"+m.sender_name+" "+m.content+"</li>");
}
}
},
One way I found to solve this problem is to render the template first, and then send the resulting text in response.
In a template file, only include the html that needs to be used in Ajax. No extra html tags. Here you can use all Django tags and filters. For example:
{% for m in messages_list %}
<li>
<b>{{ m.sender.profile.get_short_name }}</b>
({{ m.send_time|time:"H:i" }}):
{{ m.content }}
{% if m.sender == user %}
{% if m.is_seen %}
<b><small>✓✓</small></b>
{% else %}
<b><small>✓</small></b>
{% endif %}
{% endif %}
</li>
{% empty %}
<li>No messages here yet...</li>
{% endfor %}
In the view, using a function called render_to_string
, render the template and send it in context of the json response:
response = render_to_string("just_list.html", context={"messages_list": new_messages})
return JsonResponse({"messages": response})
Then it can easily be used in Ajax:
...
success: function (json) {
$('#messages-list').append(json.messages);
},