0

I want to be able to change my comments queryset without page refresh. Here are the querysets:

comment_list = Comment.objects.filter().order_by('-score__upvotes')
new_comments_list = Comment.objects.filter().order_by('-timestamp')

Then my template is

{% for comment in comment_list %}
    {{ comment }}

...

Is there any way to change {% for comment in comment_list %} to {% for comment in new_comments_list %} using AJAX (no page refresh)?

Or possibly changing the value of comment_list to equal Comment.objects.filter().order_by('-timestamp')?

EDIT

view:

def new_comments(request):
    if request.is_ajax():
        print('ajax') #prints ajax
        comment_list = Comment.objects.filter().order_by('-timestamp')
        html = render_to_string('article.html', {'comment_list': comment_list})
        return HttpResponse(html)

ajax call:

$('.comments_new').on('click', function() {
    $.ajax({
        type: 'GET',
        url: '/new_comments/',
        data: {
            csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),
        },
        success: function (data) {
            console.log(data.comment_list); // undefined
        }
    })
});
Zorgan
  • 8,227
  • 23
  • 106
  • 207

1 Answers1

1

What I guess, you are trying to use comment_list when page renders and new_comment_list using ajax without modifying

{% for comment in comment_list %}
    {{ comment }} 
{%  endfor %}

The problem with your code is comment_list is a queryset and it is evaluated on the server side, when the page is rendered (after passing through Django template engine ).Javascript doesn't understand queryset. It understands HTML or JSON. So, you have to modify your script so that it return HTML or JSON for ajax request.

I would suggest you re-write your view like:

from django.template.loader import render_to_string

if request.is_ajax(): 
     new_comments_list = Comment.objects.filter().order_by('-timestamp')
     # you can keep your_div_template as a included template in your main template
     html = render_to_string('your_div_template', {'comment_list': new_comments_list})
     return HttpResponse(html)

And write your frontend to generate this HTML code. here is a link that gives more better explanation of rendering using ajax: Returning Rendered Html via Ajax

Community
  • 1
  • 1
Vidya Sagar
  • 1,496
  • 14
  • 23
  • Can you have a look at my code in the edit? I've used your method but it doesn't seem like i'm receiving the rendered queryset on my frontend (returns undefined) – Zorgan Feb 08 '17 at 00:04
  • I'm also getting a `UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.` – Zorgan Feb 08 '17 at 03:03
  • The one this your should be pretty clear that you get a small piece of HTML.The same html which needs to replaced with comment generating div. I would say data is your HTML that needs to replaced with comment generating div. and that can be done with $('#div_id').html(data). you need not bother about csrf, I doubt why you are concerned about csrf if you are not generating a form from ajax. – Vidya Sagar Feb 08 '17 at 05:51