2009-10-06 14 views
25

Tworzę małą aplikację, która pozwala użytkownikom głosować na przedmioty w górę lub w dół. Używam Django (i nowego!).Django Metoda głosowania w górę/w dół

Zastanawiam się, jaki jest najlepszy sposób, aby zaprezentować link do strony użytkownika. Jako link, przycisk lub coś innego?

Zrobiłem już coś takiego w php z inną strukturą, ale nie jestem pewien, czy mogę zrobić to w ten sam sposób. Czy powinienem mieć metodę głosowania w górę/w dół, a następnie wyświetlić link do użytkownika, aby kliknąć. Kiedy go klikną, wykonuje on tę metodę i odświeża stronę?

Odpowiedz

11

Wystarczy podłączyć i grać:

RedditStyleVoting
Wdrażanie stylu reddit głosu dla każdego modelu z Django głosowania
http://code.google.com/p/django-voting/wiki/RedditStyleVoting

+0

Może to być przydatne. Właśnie na to patrzę. Czy wiesz, co z pliku devdocs.apps.kb.models import Link należy zmienić na? –

+2

Zaletą tego kodu w mojej odpowiedzi jest stopniowe ulepszanie - będzie działało bez Javascript, ale możesz dodać AJAX na górze, aby poprawić wygodę użytkownika. –

+3

Zastąp plik devdocs.apps.kb.models ścieżką do pliku models.py, w którym zdefiniowano link. Będzie to coś w stylu yourprojectname.yourappname.models. –

4

Jako link, przycisk lub coś innego?

Coś jeszcze, a co z obrazem?

Po kliknięciu wywołuje metodę i odświeża stronę?

Być może lepiej użyj ajax, aby wywołać metodę zapisywania głosów i nie odświeżaj niczego.

Oto, co przychodzi mi do głowy.

enter image description here

8

Cokolwiek zrobisz, upewnij się, że jest on złożony przez POST i nie GET; Żądania GET powinny nigdy zmienić informacje w bazie danych.

+0

Ma rację, a ta zasada wyklucza użycie prostego linka do obrazu, aby ponownie załadować stronę. –

30

Oto sedno mojego rozwiązania. Używam obrazów z jQuery/AJAX do obsługi kliknięć. Silny wpływ na tę stronę. Jest kilka rzeczy, które mogą przydać się do pracy (na przykład obsługa błędów w kliencie), a większość z nich mogłaby prawdopodobnie zostać refaktoryzowana, ale mam nadzieję, że kod jest dla ciebie przydatny.

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); 
       } 
      }); 
     } 
    }); 

Widok Django, który obsługuje żądania 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) 

a odpowiednie części modelu wątku:

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

Dzięki za to. Gdzie umieszczasz kod jquery? –

+2

Dołączasz plik jquery.js z tagiem skryptu do nagłówka, możesz umieścić te wewnętrzne znaczniki skryptu w dowolnym miejscu na stronie. Zwykle umieszczam go w tym samym pliku włączającym szablon django jako HTML dla tej części strony, aby pozostać razem. jquery.com to świetny zasób, jeśli zamierzasz robić rzeczy AJAX-y. –

+0

wypróbował twój kod, ale nie mogłem uzyskać przycisków do kliknięcia! –

Powiązane problemy