Reputation: 22767
This is my models.py:
class Blog(models.Model):
user = models.ForeignKey(User)
votes = models.IntegerField(default=0)
class BlogExtended(models.Model):
blog = models.ForeignKey(Blog)
usersVoted = models.ManyToManyField(User)
Basically, each blog has a user who created the blog. If users like someones blog, they can vote for it. Each time a blog gets a vote, the 'votes' counter goes up by one. In my template, I don't want the vote button to be a button which just says 'vote'. I want the vote button to be an image. Since once the user clicks the vote button, I am going to be altering the database (increasing the 'votes' field by one) I need to use a POST request. So this is what I initially had for my template (I initially used a GET request):
{% if Blogs %} <!-- Blogs is a list of blogs -->
<ul class="blogs">
{% for blog in Blogs %}
<li>
<a href="/vote/?id={{ blog.id }}" class="vote"><img src="images/voteButton.jpg" </a>
and this was my view which handles the /vote/ url:
def voteView(request):
if request.GET.has_key('id'): #if it is a GET request which has the blogs id
try:
id = request.GET['id']
blog = Blog.objects.get(id=id) #if the Blog is found
blog.votes += 1 #make a change to the 'votes' field in the DB
blog.blogextended_set.usersVoted.add(request.user) #make a change in the 'usersVoted' field in the DB
blog.save()
but as you can see, I was using GET instead of POST. I realized I needed to use POST since I am altering the database, so this was my attempt at making it a POST request:
<form method="post" action="/vote/">{% csrf_token %}
<button type="submit">
<img src="images/voteButton.jpg" alt="vote" />
<!-- I used button rather than input because with button, I was able to replace the button with an image.. I was unable to replace the button with an image -->
</button>
</form>
This form sends basically no information to /vote/ (it only sends the current user object: request.user). I need to also send the ID of the blog. I was able to send the ID the intial way by adding a query string in the URL of the GET request. The only way I can think of to add the ID of the blog in my POST request is by adding a query string in the URL, so my form would action like this:
<form method="post" action="/vote/?id={{ blog.id }}">
I realized that sending a query string with a POST request is something I have never seen / done before. Is it okay if I send a query string with a POST request or is it not recommended? What problems could arise from sending a query string with a POST request?
Additional help: If it is not recommend, can anyone suggest another way of sending additional information along with the POST request?
Upvotes: 1
Views: 2135
Reputation: 6933
You just need to add another field to your form:
<input type="hidden" name="blog_id" value="{{ blog.id }}" />
whole form:
<form method="post" action="/vote/">{% csrf_token %}
<button type="submit">
<img src="images/voteButton.jpg" alt="vote" />
</button>
<input type="hidden" name="blog_id" value="{{ blog.id }}" />
</form>
then, your view should look like:
def voteView(request):
if request.POST.has_key('blog_id'):
try:
id = request.POST['blog_id']
...
Upvotes: 2
Reputation: 1006
The better solution is the put the blog ID in a hidden field in your form, like so:
<form method="post" action="/vote/">
{% csrf_token %}
<input type="hidden" name="id" value="{{ blog.id }}">
<button type="submit">
<img src="images/voteButton.jpg" alt="vote" />
</button>
</form>
In your view, you will be able to extract the ID of the blog post that was voted for using request.POST['id']
.
Upvotes: 2