Reputation: 1135
Here is my code, shortened for brevity.
HTML Template
{% for question in questions %}
<div class="upvote"></div>
{% endfor %}
# lots of code later...
<script>
$(".upvote").click(function(){
$.ajax({
type: "POST",
url: "{% url 'upvote_for_question' %}",
data: {
'question': question
},
}
})
})
</script>
My <div class="upvote">
element is an upvote button for a question (think Stack Overflow's upvote button). As the code shows, every question
in question_list
has an upvote button.
My question is, when the user presses an upvote button, how do I pass the associated question
's pk/id to the view?
Upvotes: 1
Views: 2600
Reputation: 3364
One way would be to define url for upvote:
url(r'^questions/(?P<question_id>\w+)/upvote', views.question_upvote, name='question_upvote')
Then use the reverse url functionality in the template and pass url in the data attribute like:
{% for question in questions %}
<div class="upvote"
id="button-{{ question.pk}}"
data-href="{% url 'question_upvote' question.pk %}">{{ question.upvotes }}
</div>
{% endfor %}
And modify your jQuery to get url from data-href
attribute plus add CSRF token, otherwise POST
will fail with status 403
. Something like:
$(".upvote").click(function(){
var postData = {csrfmiddlewaretoken: '{{ csrf_token }}'}
$.ajax({
type: "POST",
url: $(this).attr("data-href"),
data: postData,
success: function(new_number_of_upvotes) {
$(this).html(new_number_of_upvotes)
}
})
})
Updated view reflecting these changes would be something in the sense of:
def question_upvote(request, question_id):
if request.is_ajax() and request.method == 'POST':
question = get_object_or_404(Questions, pk=question_id)
question.upvotes += 1
question.save()
return HttpResponse(question.upvotes)
else:
return HttpResponseRedirect('/')
I haven't tested this, but I guess it should work.
Upvotes: 4
Reputation: 996
You could first give each div a unique id
:
{% for question in questions %}
<div class="upvote" id="button-{{ question.pk}}"></div>
{% endfor %}
Then pass that in the post data:
data: {
'question': $(this).attr('id')
},
Upvotes: 2