2009-10-06 3 views
25

Я делаю небольшое приложение, которое позволяет пользователям голосовать за элементы вверх или вниз. Я использую Django (и новичок в этом!).Django Vote Up/Down method

Я просто задаюсь вопросом, что является лучшим способом представить ссылку upvote пользователю. Как ссылку, кнопку или что-то еще?

Я уже сделал что-то подобное в php с другой структурой, но я не уверен, могу ли я сделать то же самое. Должен ли я иметь метод для голосования вверх/вниз, а затем отображать ссылку на пользователя для клика. Когда они нажимают на него, он выполняет метод и обновляет страницу?

ответ

11

Просто подключи и играй:

RedditStyleVoting
Реализация голосования Reddit стиль для любой модели с Джанго голосования
http://code.google.com/p/django-voting/wiki/RedditStyleVoting

+0

Это может быть полезно. Просто посмотри на это сейчас. Знаете ли вы, что от devdocs.apps.kb.models import Ссылка следует изменить на? –

+2

Преимущество этого кода в моем ответе - прогрессивное улучшение - оно будет работать без Javascript, но вы можете добавить AJAX сверху, чтобы улучшить работу пользователя. –

+3

замените devdocs.apps.kb.models на путь к файлу models.py, где вы определяете ссылку. Это будет что-то вроде yourprojectname.yourappname.models. –

4

Как ссылка, кнопка или что-то еще?

Что-то еще, а как насчет изображения?

Когда они нажимают на него, он выполняет метод и обновляет страницу?

Возможно, вы могли бы лучше использовать ajax, чтобы вызвать метод сохранения голоса, а не обновлять что-либо вообще.

Это то, что приходит мне на ум.

enter image description here

8

Все, что вы делаете, убедитесь, что он представлен POST, а не GET; Запросы GET должны никогда изменить информацию о базе данных.

+0

Он прав, и этот принцип исключает использование простой ссылки изображения для перезагрузки страницы. –

30

Вот суть моего решения. Я использую изображения с jQuery/AJAX для обработки кликов. Сильное влияние на этот сайт. Есть некоторые вещи, которые могли бы использовать некоторую работу (например, обработка ошибок в клиенте - и многое из этого, возможно, было бы реорганизовано), но, надеюсь, код вам полезен.

HTML-:

 <div class="vote-buttons"> 
     {% ifequal thisUserUpVote 0 %} 
     <img class="vote-up" src = "images/vote-up-off.png" title="Vote this thread UP. (click again to undo)" /> 
     {% else %} 
     <img class="vote-up selected" src = "images/vote-up-on.png" title="Vote this thread UP. (click again to undo)" /> 
     {% endifequal %} 
     {% ifequal thisUserDownVote 0 %} 
     <img class="vote-down" src = "images/vote-down-off.png" title="Vote this thread DOWN if it is innapropriate or incorrect. (click again to undo)" /> 
     {% else %} 
     <img class="vote-down selected" src = "images/vote-down-on.png" title="Vote this thread DOWN if it is innapropriate or incorrect. (click again to undo)" /> 
     {% endifequal %} 
     </div> <!-- .votebuttons --> 

JQuery:

$(document).ready(function() { 

    $('div.vote-buttons img.vote-up').click(function() { 

     var id = {{ thread.id }}; 
     var vote_type = 'up'; 

     if ($(this).hasClass('selected')) { 
      var vote_action = 'recall-vote' 
      $.post('/ajax/thread/vote', {id:id, type:vote_type, action:vote_action}, function(response) { 
       if (isInt(response)) { 
        $('img.vote-up').removeAttr('src') 
         .attr('src', 'images/vote-up-off.png') 
         .removeClass('selected'); 
        $('div.vote-tally span.num').html(response); 
       } 
      }); 
     } else { 

      var vote_action = 'vote' 
      $.post('/ajax/thread/vote', {id:id, type:vote_type, action:vote_action}, function(response) { 
       if (isInt(response)) { 
        $('img.vote-up').removeAttr('src') 
         .attr('src', 'images/vote-up-on.png') 
         .addClass('selected'); 
        $('div.vote-tally span.num').html(response); 
       } 
      }); 
     } 
    }); 

мнение Джанго, который обрабатывает запрос AJAX:

def vote(request): 
    thread_id = int(request.POST.get('id')) 
    vote_type = request.POST.get('type') 
    vote_action = request.POST.get('action') 

    thread = get_object_or_404(Thread, pk=thread_id) 

    thisUserUpVote = thread.userUpVotes.filter(id = request.user.id).count() 
    thisUserDownVote = thread.userDownVotes.filter(id = request.user.id).count() 

    if (vote_action == 'vote'): 
     if (thisUserUpVote == 0) and (thisUserDownVote == 0): 
     if (vote_type == 'up'): 
      thread.userUpVotes.add(request.user) 
     elif (vote_type == 'down'): 
      thread.userDownVotes.add(request.user) 
     else: 
      return HttpResponse('error-unknown vote type') 
     else: 
     return HttpResponse('error - already voted', thisUserUpVote, thisUserDownVote) 
    elif (vote_action == 'recall-vote'): 
     if (vote_type == 'up') and (thisUserUpVote == 1): 
     thread.userUpVotes.remove(request.user) 
     elif (vote_type == 'down') and (thisUserDownVote ==1): 
     thread.userDownVotes.remove(request.user) 
     else: 
     return HttpResponse('error - unknown vote type or no vote to recall') 
    else: 
     return HttpResponse('error - bad action') 


    num_votes = thread.userUpVotes.count() - thread.userDownVotes.count() 

    return HttpResponse(num_votes) 

и соответствующие части модели резьбы:

class Thread(models.Model): 
    # ... 
    userUpVotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes') 
    userDownVotes = models.ManyToManyField(User, blank=True, related_name='threadDownVotes') 
+0

Спасибо за это. Где вы помещаете код jquery? –

+2

Вы включаете файл jquery.js с тегом скрипта в заголовке, тогда вы можете прикреплять эти теги внутри сценария в любом месте страницы. Я обычно заканчиваю тем, что помещаю его в тот же шаблон django, который включает в себя файл в качестве HTML для этой части страницы, чтобы они оставались вместе. jquery.com - отличный ресурс, если вы собираетесь начать делать вещи AJAX-y. –

+0

попробовал ваш код, но я не мог заставить кнопки переключаться! –

 Смежные вопросы

  • Нет связанных вопросов^_^