Search code examples
pythondjangoformscsrfdjango-csrf

Django CSRF verfication failed


I am new to Django and I have a problem with CSRF verification. I have so far created Django POST forms that are successful and have no CSRF errors. But when I try to create the following form, I get CSRF verification failure: "CSRF token missing or incorrect".

{% for a in answers %}
    {% csrf_token %}
    <form class="" action="." method="post">
        <input type="submit" value="{{ a.answer }}" name={{a.answer_id}}></input>
    </form>
    <p>Number of votes: {{ a.votes }}</p>
{% empty %}
    <p>There are no answers for the poll</p>
{% endfor %}

Here is what the models look like:

class Question(models.Model):
    date_added = models.DateTimeField(auto_now_add=True)
    question = models.CharField(max_length=200)
    number_of_answers = models.IntegerField(default=0)

class Answer(models.Model):
    question = models.ForeignKey(Question)
    answer = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

Here is what the view function for that form looks like (so far I haven't added any code to process the post request):

def poll(request, question_id):
    if request.method == "POST":
        pass
    poll = Question.objects.get(id=question_id)
    answers = poll.answer_set.order_by()
    context = {'poll' : poll, 'answers' : answers}
    return render(request, 'polls/poll.html', context)

Basically, for each question there are multiple answers. I want to allow the user to click the button associated to a particular answer. Once the user clicks a button, I want to increase the vote for that answer in the database (I haven't added the code to do this yet, but this is the goal). I then want the page to reload with the newly added vote.

Here is just an example of what this looks like visually

Does anybody know what I am doing wrong or what I am missing?

Thank you!


Solution

  • The csrf token goes inside the form:

    <form class="" action="." method="post">
     {% csrf_token %} <!--here goes the token-->
        <input type="submit" value="{{ a.answer }}" name={{a.answer_id}}></input>
    </form>