发布多个表单时的 Django csrf 令牌

Django csrf token when posting multiple forms

我正在尝试创建一个包含多个表单的页面,我想构建类似 "like button" 的内容,以便我可以在页面中 "like" 一些 post。我也想设置一些限制,这样我可以喜欢每个 post,但只能喜欢每个 post 一次

现在遇到一个问题,只能"like"一个post。当我点击另一个 "like" 到另一个 post 时,会发生 csrf 错误(CSRF 验证失败。请求中止。)。我想知道如何同时在一个页面中点赞多个 post。

它与{% csrf_token %}的放置方式和位置有关系吗?这篇文章(How Will the Inclusion of Two Forms Affect my CSRF Token Use?)说我应该把{% csrf_token %}放在每一个表格中,但它似乎不起作用。

这是我的代码:

models.py

class Restaurant(models.Model):
    name = models.CharField(max_length=20)
    phone_number = models.CharField(max_length=15)
    address = models.CharField(max_length=50, blank=True)
    likes = models.DecimalField(max_digits=2,decimal_places=0, default=0)

views.py

<!doctype html>
<html>
<head>
    <title> Menu </title>
    <meta charset='utf-8'>
</head>
<body>
    <h2>餐廳列表</h2>

    <table>
        <tr>
            <th>ID</th>
            <th>NAME</th>
            <th>PHONE</th>
            <th>ADDRESS</th>
            <th>LIKES</th>
            <th>LIKE IT!</th>
        </tr>
        {% for r in restaurants %}
            <tr>
                <td> {{ r.id }} </td>
                <td> {{ r.name }} </td>
                <td> {{ r.phone_number }} </td>
                <td> {{ r.address }} </td>
                <td> {{ r.likes }} </td>
                <td>
                <form id={{ r.id }} action="" method="post">
                    {% csrf_token %}
                    <input type="hidden" name="ok" value="yes">
                    <input class="submit" type="submit" value="Upvote">
                </form>
                </td>

            </tr>
        {% endfor %}
    </table>

    </form>
</body>
</html>

views.py

def list_restaurants(request):
    restaurants = Restaurant.objects.all()

    if request.method == "POST":
        post = Restaurant.objects.get(id=request.POST['id'])
        post.likes += 1
        post.save()
        return render_to_response('restaurants_list.html',locals())
    else:
        return render(request, 'restaurants_list.html',locals())

改变

return render_to_response('restaurants_list.html',locals())

return render(request, 'restaurants_list.html',locals())