Джанго, JQuery, Аякс; обновление div для системы голосования не работает?

У меня есть работающая система голосования django, использующая нажатия клавиш вверх и вниз для записей в базе данных.

Мне нужно обновить {{ entry.score }} на странице без перезагрузки, так как на странице будут другие записи. {{ entry.text }} может обновляться, но должен оставаться одной и той же записью, пока другое нажатие клавиши не выберет другую запись.

Я пытаюсь сделать это с помощью ajax, но получаю 500 Internal Server Error и не обновляюсь,

GET http://127.0.0.1:8000/voteup/?voteid=30 500 (INTERNAL SERVER ERROR) jquery.min.js:4
send jquery.min.js:4
n.extend.ajax jquery.min.js:4
n.(anonymous function) jquery.min.js:4
(anonymous function) (index):76
n.event.dispatch jquery.min.js:3
r.handle

хотя голосование проходит правильно...

(индекс): 76 в голосовании.html: $.get("/voteup/", args).done(функция(данные) {

voting.html

 <div class = "table">
  <div id="Vote" class = "vote">
  <div style="text-align: left">
  {% for entry in voting_entry_list %} 
    <li><a href="/entries/{{ entry.id }}/">{{ entry.text }}&nbsp{{ entry.score }}</a></li>
    <p>
    <input type="submit" id="voteid" name='voteid' value="{{ entry.id }}" autofocus value="" onfocus="this.value = this.value;" class = "transparent"/>
          <script>
          var data = '#Vote';
          var url = "/voting/";
            $(document).ready(function() {
              $("#voteid").bind("keydown", function(e) { //input #submit?????
                if (e.keyCode == 38) {
                  var text = $("#voteid").val();        
                  var args = {'voteid':text};       
                  $.get("/voteup/", args).done(function(data) {
                    console.log("message: " + data);
                        $.ajax({      
                            url: url,
                            data: data,
                            dataType: 'html',
                            success: function(data){
                                $(this).html(data); //this?
                            }   
                        });
                  });
                return false;
                }       
              });
            });     
          </script>
     {% endfor %}
      </div>
      </div>
  </div>

views.py

def index(request):   
   context = { # actually one item, command from extended object manager
     'voting_entry_list': Entry.objects.unvoted_or_random(), 
   }     
   return render(request, 'entries/index.html', context); 

def voting(request):
    context = {'voting_entry_list': Entry.objects.random(),}      
    return render(request, 'entries/voting.html', context);

def voteup(request):
    voting_id = request.GET.get('voteid') 
    e = Entry.objects.unvoted_or_random()
    context = {'voting_entry_list': e,}
  if request.method=='GET':
    v = Entry.objects.get(pk=voting_id)
    v.score +=1 
    v.voted=True 
    v.save() 
    context = {'voting_entry_list': v,}
  else:
    pass
  return render(request, 'entries/voting.html', context);

Models.py

class EntryManager(models.Manager): #a basic extention to the model basemanager to insert new sorting
def unvoted_or_random(self): # command definition uses models input
    unvoted_entries = self.filter(voted = False).order_by('-pub_date') # sorted by youngest unvoted entries from any user
    voted_entries = self.filter(voted = True).order_by('?') # if no unvoted entries, voted boolean enables random selection '?'  
    if unvoted_entries: # for boolean unvoted
        return unvoted_entries[:1] # return latest
    else: # for boolean voted
        return voted_entries[:1] # return random

person Helmut Applebaum    schedule 10.08.2014    source источник
comment
Это означает, что в вашем бэкэнд-коде есть ошибка. И вы не показали ни ошибку (из лога сервера), ни сам код бэкенда. Так что этот вопрос без ответа.   -  person Daniel Roseman    schedule 10.08.2014
comment
@DanielRoseman Спасибо за конструктивный совет, я добавил необходимое (я считаю), поэтому надеюсь, что теперь это презентабельно для некоторой помощи ...   -  person Helmut Applebaum    schedule 10.08.2014
comment
КСТАТИ, polling_entry_list — это только одна запись!   -  person Helmut Applebaum    schedule 10.08.2014


Ответы (1)


У меня только что была сессия с аспирантом в университете, и он направил меня на правильный путь.

Основная проблема, с которой я столкнулся, касалась философии использования Jquery и Ajax, которую мне было трудно почерпнуть из руководств и онлайн-поддержки, которые, как я обнаружил, непрозрачны в отношении самых основ для простых задач. С этой целью я представлю здесь окончательный код в надежде, что он поможет людям, начинающим с подобной простой системы голосования.

Благодаря обновить div в Django с помощью JQuery и AJAX Перезагрузить всю страницу в Ajax на Django? Как правильно обновить div с помощью Jquery/Ajax в шаблоне Django Передача списка значений в представление django с помощью вызова jQuery ajax По мелочам...


Обновление голосования без изменения записи (нажатие кнопок)


Моя главная проблема заключалась в том, что я сделал для URL-адреса и данных. Оказывается, у меня был не тот конец палки. Данные в моем случае возвращаются из представлений .get (я думал, что это идентификатор записи, который мне нужно передать для обновления), и мне не нужно было определять URL-адрес для очень простой системы, которую я делал.

Итак:

voting.html

var data = '#Vote';
var url = "/voting/";

$.ajax({      
     url: url,
     data: data,
     dataType: 'html',
     success: function(data){
     $(this).html(data);
  } 

Стало таким:

$("#score").text(data); //span updates score with new value from views

Чтобы обновить баллы по мере их голосования. Span в ссылке выше этого кода позволил мне получить доступ к счету:

<span id="score">{{ entry.score }}</span>

И единственное, что мне нужно было сделать, это добавить это к представлениям в голосовании (запрос) или голосовании (запрос), когда я обращался к моделям входа и добавлял голосование:

views.py

return HttpResponse(v.score)

Это заботится о голосовании вверх и вниз. Когда вы нажимаете кнопки со стрелками вверх и вниз, запись остается прежней, но голоса обновляются из представлений после сохранения в базе данных.


Ключ для изменения записи с обновлением


Чтобы изменить запись (на новую случайную запись), .get для клавиши со стрелкой вправо возвращает строку с идентификатором, текстом и оценкой случайной записи;

views.py

def random_entry(request):
e = Entry.objects.random()[0]
return HttpResponse("%s,%s,%s" % (e.id, e.text, e.score))

Какой файл голосования.html разбивает и обновляет текст и оценку, а также изменяет текущий идентификатор:

voting.html

if(e.keyCode == 39) { //right key
     $.get("/random-entry/", {}).done(function(data) {
         var parts = data.split(",");
          $("#entry-text").text(parts[1]);
          $("#score").text(parts[2]);
          currentid = parts[0];
          console.log("random entry data: " + data);
         });
        return false;}

Итак, основные изменения. Я включаю полный код ниже в надежде, что он кому-то поможет;

voting.html

 <div class = "table">
  <div id="Vote" class = "vote">
  <div style="text-align: left">
  {% for entry in voting_entry %} 
    <li><a href="/entries/{{ entry.id }}/"><span id="entry-text">{{ entry.text }}</span> <span id="score">{{ entry.score }}</span></a></li>
    <p>
    <input type="submit" id="voteid" name='voteid' value="{{ entry.id }}" autofocus value="" onfocus="this.value = this.value;" class = "transparent"/>
          <script>
            $(document).ready(function() {
            var currentid = {{entry.id}}; //entry id is defined
              $("#voteid").bind("keydown", function(e) {
                if (e.keyCode == 38) {  //up arrow key
                  var args = {'voteid':currentid }; //current id is used
                  $.get("/voteup/", args).done(function(data) { //when .get is done, returns data from views(score)                   
                    console.log("message: " + data);
                    $("#score").text(data); //span updates score with new value from views
                  });
                return false;
                }
                if (e.keyCode == 40) { //down arrow key
                  var args = {'voteid':currentid };     //current id is used
                  $.get("/votedown/", args).done(function(data) { //when .get is done, returns data from views(score)
                    console.log("message: " + data);  
                    $("#score").text(data); //span updates score with new value from views
                  });
                return false;
                }
                if(e.keyCode == 39) { //right key
                  $.get("/random-entry/", {}).done(function(data) {
                    var parts = data.split(",");
                    $("#entry-text").text(parts[1]);
                    $("#score").text(parts[2]);
                    currentid = parts[0];
                    console.log("random entry data: " + data);
                  });
                 return false; 
                 }      
              });
            });     
          </script>
     {% endfor %}
      </div>
      </div>
  </div>    

views.py

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from entries.models import Entry
from datetime import datetime
from django.utils import timezone
from django.views.decorators.csrf import csrf_protect

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

def add(request):
 created_date = default=datetime.now()
 created_text = request.GET.get('text')    
 e = Entry(text=created_text,pub_date=created_date) 
 e.save()       
 return HttpResponse('done')

def enter(request):
 return render(request, 'entries/enter.html'); 

def top(request):
 context = {
  'high_entry': Entry.objects.order_by('-score','-pub_date')[:1],
 }
 return render(request, 'entries/top.html', context);

def voting(request):
 context = {'voting_entry': Entry.objects.random(),}      
 return render(request, 'entries/voting.html', context);

def random_entry(request):
 e = Entry.objects.random()[0]
 return HttpResponse("%s,%s,%s" % (e.id, e.text, e.score))

def voteup(request):
 voting_id = request.GET.get('voteid')
 if request.method=='GET':
    v = Entry.objects.get(pk=voting_id)
    v.score +=1
    v.voted=True
    v.save()
    return HttpResponse(v.score)
 else:
    pass
 return HttpResponse('done')   

def votedown(request):
 voting_id = request.GET.get('voteid')
 if request.method=='GET':
    v = Entry.objects.get(pk=voting_id)
    v.score -=1
    v.voted=True
    v.save()
    return HttpResponse(v.score)
 else:
    pass
 return HttpResponse('done')
person Helmut Applebaum    schedule 11.08.2014