Método de votación arriba / abajo de Django

Estoy creando una pequeña aplicación que permite a los usuarios votar elementos hacia arriba o hacia abajo. Estoy usando Django (¡y nuevo en eso!).

Me pregunto cuál es la mejor manera de presentar el enlace de voto a los usuarios. ¿Como enlace, botón o algo más?

Ya he hecho algo como esto en PHP con un marco diferente, pero no estoy seguro de poder hacerlo de la misma manera. Debería tener un método para votar arriba / abajo y luego mostrar un enlace al usuario para hacer clic. Cuando hacen clic en él, realiza el método y actualiza la página?

Sólo enchufar y jugar:

RedditStyleVoting
Implementación de la votación estilo reddit para cualquier modelo con django-vote
http://code.google.com/p/django-voting/wiki/RedditStyleVoting

Aquí está la esencia de mi solución. Uso imágenes con jQuery / AJAX para manejar los clics. Fuertemente influenciado por este sitio. Hay algunas cosas que podrían requerir algo de trabajo (manejo de errores en el cliente, por ejemplo, y gran parte de esto probablemente podría ser refaccionado) pero es de esperar que el código sea útil para usted.

El HTML:

{% ifequal thisUserUpVote 0 %} {% else %} {% endifequal %} {% ifequal thisUserDownVote 0 %} {% else %} {% endifequal %}

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

La vista de Django que maneja la solicitud 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) 

Y las partes relevantes del modelo Thread:

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

Hagas lo que hagas, asegúrate de que sea enviado por POST y no GET; Las solicitudes GET nunca deben alterar la información de la base de datos.

¿Como enlace, botón o algo más?

Algo más, ¿qué pasa con una imagen?

Cuando hacen clic en él, realiza el método y actualiza la página?

Tal vez podría utilizar mejor ajax para invocar un método para guardar la votación, y no actualizar nada.

Esto es lo que viene a mi mente.

introduzca la descripción de la imagen aquí