Search code examples
javascriptjqueryajaxdjangorating

How to refresh parts of a page in Django + jQuery?


I have created a demo project where I have two links named '1' and '2', and a display of the number 1 or 2 depending on whichever link is clicked.

models.py

class Count(models.Model):
    num = models.IntegerField(default=0)

urls.py

urlpatterns = [
    url(r'^home/$', views.home, name='home'),
    url(r'^count/(?P<pk>\d+)/$', views.count, name='count'),
]

views.py

def home(request):
    c = Count.objects.filter(id=1)
    return render(request, "alpha/home.html", {'c': c})

def count(request, pk):
    c = Count.objects.filter(id=1).update(num=pk)
    return HttpResponseRedirect(reverse('alpha:home'))

home.html

<html>
<head>
    <script type="text/javascript" src="jquery-2.1.4.min.js"></script>
</head>

<body>
{% for c in c %}
    <span id="num"> {{ c.num }} </span>
{% endfor %}

<a href="#" onclick="$.ajax({
            url: '{% url 'alpha:count' 1 %}',
            success: function(data) {
                $('#num').text({{ c.num }});
                }
            })">1</a>
<a href="{% url 'alpha:count' 2 %}">2</a>
</body>
</html>

As you can see that the count view updates the model and then reloads the home view, thus refreshing the answer (which is 1 or 2). But in the template file I have tried to include jQuery library and tried to call the first link in such a way that the page doesn't reload. I know very little JS, so this is basically copy/paste code. And clicking the first link doesn't do anything right now. What is it that I am doing wrong?


Solution

  • Your count view should return Count value and not redirect:

    def count(request, pk):
        c = Count.objects.filter(id=1).update(num=pk)
        return new HttpResponse(pk)
    

    Your AJAX call should update span's value based on the response from the server:

    $.ajax({
        url: '{% url 'alpha:count' 1 %}',
        success: function(data) {
            $('#num').text(data);
        }
    })
    

    Additionally I'd extract AJAX into a function, eg:

    function updateCount(value){
        $.ajax({
            url: '/count/' + value,
            success: function(data) {
                $('#num').text(data);
            }
        })
    }
    

    and then reuse it twice in your HTML:

    <a href="#" onclick="updateCount(1);">1</a>
    <a href="#" onclick="updateCount(2);">2</a>