furyhunter
furyhunter

Reputation: 139

how can I use django templates variable in javascript section?

I'm on little task of django and I put some JavaScript section for endless scroll,

here is part of my html file.

{% for d in data reversed %}
<form method="POST" action="/SNS/{{d.id}}/">
{% csrf_token %}

<li>
<h5>{{d.content}}</h5>
<p>
    {{d.date}}
    <button type="submit" name="delete" value="delete">X</button>
</P>
</li>
</form>

{% endfor %}

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="script.js"></script>

<script type="text/javascript">
    var d = "{{data}}";
    $(window).scroll(function() {
        if($(window).scrollTop() == $(document).height() - $(window).height()) {
            alert('End of Window');


        }
    });

</script>

data comes from views and it works well in html part.

but problem is this :

I want to use data variable in my script section.

so I declare var d like that, but it didn't work.

how can I use var from django in JavaScript?


edited : what I want to do ultimately is twitter-like endless scroll.

enter image description here

datas are in db, and page load some of them at first.

when user scroll down the page, page load some of the remain data.. ans so on.

I wrote code for scrolling down event, and I need to show the remaining data

Upvotes: 0

Views: 1822

Answers (3)

Leonard2
Leonard2

Reputation: 890

here is what I usually do:

models.py

class MODEL(models.Model):
    field1 = models.CharField()
    field2 = models.TextField()
    field3 = models.DateField()

    def as_dict(self):
        return {'id':self.id, 'field1': self.field1, 'field2': self.field2, 'field3': self.field3}

views.py

import json
from django.core.serializer.json import DjangoJSONEncoder

#... inside some view ...
    context = {}
    json = [ q.as_dict() for q in SOMEQUERYSET ]
    context['json'] = json.dumps(json, cls=DjangoJSONEncoder)

Javascript in HTML

var d = {{json|safe}};

Upvotes: 1

AlmasK89
AlmasK89

Reputation: 1340

You can separate you templates to simple request and ajax call. For example:

View function:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def datalist_ajax(request):
data = Data.objects.all().order_by('created')
per_page = 1
paginator = Paginator(data,per_page)
if request.is_ajax():
    current_page = request.GET.get('page',1)
    try:
        data = paginator.page(current_page)
    except PageNotAnInteger:
    # If page is not an integer, deliver first page.
        data = paginator.page(1)
    except EmptyPage:
    # If page is out of range (e.g. 9999), deliver last page of results.
        data = None
    return render(request,'data/list_ajax.html',{'data':data})
else:
    return render(request,'data/list.html',{'data':paginator.page(1)})

list_ajax.html:

{% if data %}
     {% for d in data reversed %}
      <li>
       <form method="POST" action="/SNS/{{d.id}}/">
        {% csrf_token %}

        <h5>{{d.content}}</h5>
        <p>
            {{d.date}}
            <button type="submit" name="delete" value="delete">X</button>
        </P>

        </form>
      </li>
    {% endfor %}
{% else %}
    That is all
{% endif %}

list.html:

    <ul class="data-list">
        {% for d in data reversed %}
      <li>
        <form method="POST" action="/SNS/{{d.id}}/">
        {% csrf_token %}


        <h5>{{d.content}}</h5>
        <p>
            {{d.date}}
            <button type="submit" name="delete" value="delete">X</button>
        </P>

        </form>
      </li>
        {% endfor %}
    </ul>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
        <script src="script.js"></script>

        <script type="text/javascript">
            var current_page = 1;
                $(window).scroll(function () {
                    if ($(window).scrollTop() == $(document).height() - $(window).height()) {
                        current_page += 1;
                        $.ajax({
                            method: 'get',
                            url: '/data/',
                            data: {
                                'page': current_page
                            }
                        }).done(function (data) {
                            $('.data-list').append(data)
                            console.log(data);
                        });
                    }
                });

        </script>

in list.html you can extend any another "parent" template. In list_ajax.html you don't need to extend it.

Upvotes: 2

Aaron D
Aaron D

Reputation: 7700

The method you are trying will work for simple data like strings and integers, but will not work for more complex data types such as lists and dictionaries. These need to be converted into JavaScript objects using a JSON filter.

This also presents a security risk for cross-site scripting (XSS) attacks, if you are passing data that was supplied by a user to the JavaScript. I recommend you read this discussion on the Django issue tracker where they talk about it (including some example XSS vulnerability code) to see when and how you should use it.

You can convert the data to JSON by using the json module in Python, and then passing the data to your template:

template.render(Context("data": data, "jsdata": json.dumps(data)))

Or you can use an extension to filter the JSON within the template, rather than passing the data twice.

Upvotes: 2

Related Questions