Question

I have a simple entry and display system for short texts on a single web page. The text input is just an input field with a GET in views. I'd like a very basic up or down voting system on the page for the latest entries. I can get the latest entries into a variable...

Some people online have hinted that a variable can be passed to the js, and this is my first port of call before anything further.

I have not used forms or POST yet, as it seems to include urls and code unnecessary to my basic needs. Can anyone advise me on how I can pass my variable to js?

Here's some snippets of code;

template

<script type="text/javascript"> 
{% for entry in voting_entry %}
    var votingEntry="{{entry.id}}"         
    {% endfor %}     
</script>

<script type="text/javascript" src="{{STATIC_URL}}vote.js"></script>

vote.js

$(document).ready(function() {

$("#votingEntry").bind("keypress", function(e) {

    if (e.keyCode == 38) {
        var vote = $("#votingEntry").val();     
        var args = {'vote':vote};           
        $.get("/vote/", args).done(function(data) {
        location.reload();  
      });
    }   
  });

views

def index(request):
  context = {
  'latest_entry_list': Entry.objects.order_by('-pub_date')[:10],
  'high_entry_list': Entry.objects.order_by('-score')[:10],
  'low_entry_list': Entry.objects.order_by('score')[:10],
  'voting_entry': Entry.objects.order_by('-pub_date')[:1],
  }
   return render(request, 'entries/index.html', context);

*snip*

def vote(request):
  voting_id = request.GET.get('vote')
  v = Entry.objects.get(pk='voting_id')
  v.score +=1
  v.save()       
  return HttpResponse('votedone')
Was it helpful?

Solution 2

Sorted it with a very simple form in template. The submit buttons trigger a views.vote function by url, the views.vote detects up or down button names, and saves a vote to the entry referenced by entryid. This is brought in by a POST.get on the hidden name in the template form.

Lastly, a redirect keeps it all on one page and refreshes the index.

template

<ul>
{% for entry in voting_entry_list %}
    <li><a href="/entries/{{ entry.id }}/">{{ entry.text }}{{ entry.score }}</a></li>
    <li><form method="POST" action="/vote/" >
    {% csrf_token %}
      <input type="hidden" name="voteid" value="{{ entry.id }}" />
      <input type="submit" name='voteup' value="Up" />
      <input type="submit" name='votedown' value="Down" />
    </form><li>  
{% endfor %}  
</ul> 

urls

urlpatterns = patterns('',
  url(r'^admin/', include(admin.site.urls)),
  url(r'^index/$', 'entries.views.index'),
  url(r'^add/$', 'entries.views.add'),
  url(r'^vote/$', 'entries.views.vote')
)

views

@csrf_protect  
def vote(request):
 voting_id = request.POST.get('voteid',None)
 if request.method=='POST':
   if 'voteup' in request.POST:
     v = Entry.objects.get(pk=voting_id)
     v.score +=1
     v.save()
   if 'votedown' in request.POST:
     v = Entry.objects.get(pk=voting_id)
     v.score -=1
     v.save()
 else:
    pass
 return HttpResponseRedirect('/index')

My final issue was having to take the quotes off the - pk=voting_id - to prevent an error of "invalid literal for int() with base 10".

Hope this helps someone else who just wants to start with these systems in a basic manner, but something not quite the same as the django polls tutorials. It was a bit tough wading through the various methods of doing it (JSON, js, POST, forms, regex, urls, etc.), so here is the way I did it with various snippets from many SO questions.

OTHER TIPS

It's not very clear what you are trying to do. In the first snippet you repeatedly set the same variable, votingEntry, to a string containing an ID from a list. Since you set the same variable each time, the var will end up with only the last value from the list.

Additionally, in order to set a global variable outside a function in JS, you need the var keyword.

However, I'm not quite sure why you are doing any of this, because you're then not using the votingEntry variable anywhere else in your JS. You need to provide more detail about what you are hoping to achieve.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top