Short version:
After ajax call, link turns into plain text, but back to link on page refresh.
Details:
I have a notification system in place (like Stack Overflow and whatnot). The notifications are either in a dropdown subtemplate:
notification_menu_list.html
{% load display_tags %} {% load item_tags %}
<div id='notification_header'>{{ request.user|count_unread_notifications }} notification{{ request.user|count_unread_notifications|pluralize}}</div>
<ul id='notification_box'>
{% for notification in request.user|get_notifications|slice:"6" %}
{% if notification.active %}
<li class='unread notification' id='{{notification.pk}}'>{{notification.headline|safe}}</li>
{% else %}
<li class='read notification' id='{{notification.pk}}'>{{notification.headline|safe}}</li>
{% endif %}
{% endfor %}
<li class='notification all_notifications_link'><a href='{% url "notifications" %}'>Show all</a></li>
</ul>
or in a django-table with more details:
tables.py
class NotificationTable(tables.Table):
tr_class = tables.BooleanColumn(
visible=False,
empty_values=(),
accessor='active',
)
selection = tables.columns.CheckBoxColumn(
accessor="pk",
attrs={"th__input": {"onclick": "toggle(this)"}},
orderable=False)
message = tables.Column(
accessor='body',
verbose_name='Message')
def render_message(self, value):
return mark_safe(value)
created_date = tables.DateTimeColumn()
def render_tr_class(self, value):
if value is False:
return 'read'
elif value is True:
return 'unread'
class Meta:
model = Notification
They both render correctly. On the table, I can select notifications, and click 'Mark as Read' which processes the form through an ajax call and sets 'active' to False. On the dropdown, clicking a notification (which is often a link) will trigger an ajax call to mark_single_notification_as_read:
views.py:
def mark_notifications_as_read(request):
if request.method == 'POST':
selected_pks = request.POST.getlist('selection')
selected_pks = [int(pk) for pk in selected_pks[0].split(',') if pk != 'on']
Notification.objects.filter(pk__in=selected_pks).update(active=False)
table = build_notifications_table(request).as_html()
return HttpResponse(json.dumps(table), content_type='application/json')
def mark_single_notification_as_read(request):
if request.method == 'POST':
notification_id = request.POST.get('notification_id')
Notification.objects.filter(pk=int(notification_id)).update(active=False)
return render(request,
'notifications/notifications_menu_list.html',
{})
else:
print 'not post'
Either way, once the ajax completes, the links turn into plain text. If I refresh the page, they are back. I can't figure out why. Any thoughts?
EDITED:
Forgot the ajax. Why in the world would that be important?
$("#notification_container").on('click', 'li.unread', function(){
notification_id = $(this).attr('id');
$.ajax({
type: 'POST',
url: "{% url 'mark_single_notification_as_read' %}",
data: {'notification_id' : notification_id},
success: function(data){
$('#notification_container').html(data);
}
});