Django的。如何发表评论? - 最简单的例子。 CSRF验证失败

时间:2014-07-11 09:47:32

标签: python django comments foreign-key-relationship django-csrf

我想创建一个非常简单的网站,每个人都可以发一首诗,每个人都可以评论其他诗歌。所以:模板上有一首诗,还有很多评论。我知道,有Django-disqus - 框架用于评论,但我是Django的新手,所以我想逐步学习,当时Django-disqus对我来说太难了。
我尝试这样做,仅仅是为了培训:

models.py:

from django.db import models

class Poem(models.Model):
    title = models.CharField(max_length = 200)
    text = models.TextField()
    like = models.IntegerField(default = 0)


def __str__(self):
    return self.title

class Comment(models.Model):
    title = models.CharField(max_length = 200)
    text = models.TextField()
    nick = models.CharField(max_length= 100)
    poem = models.ForeignKey(Poem, null=True)

views.py:

from django.core.context_processors import csrf
from django.http import HttpResponseRedirect

from poems.models import Poem, Comment

def comment(request, poem_id):
    if poem_id:
        if request.method == 'POST':
            title = request.POST.get('title')
            text_of_comment = request.POST.get('text_of_comment')
            nick = request.POST.get('nick')
            comment = Comment.objects.create(title = title, text = text_of_comment, nick = nick, poem = Poem.objects.get(id=poem_id))
            comment.save()
            comments = Poem.objects.get(id = poem_id)
            all_comments = comments.comment_set.all()
            args = {}
            args.update(csrf(request))
            args['all_comments'] = all_comments
            return HttpResponseRedirect('/poems/get/%s' % poem_id, args)
        else:
            comments = Poem.objects.get(id = poem_id)
            all_comments = comments.comment_set.all()
            args = {}
            args.update(csrf(request))
            args['all_comments'] = all_comments
            return HttpResponseRedirect('/poems/get/%s' % poem_id, args)

urls.py:

url(r'^comment/(?P<poem_id>\d+)/$', 'poems.views.comment')

poems.html:

{%  extends "base.html"  %}


{%  block sidebar  %}
        <ul>
            <li><a href="{%  url 'poems.views.poems'  %}">Poems</a></li>
        </ul>
{%  endblock  %}

{%  block content  %}


<h2>{{  poem.title  }}</h2>
<p>{{  poem.text  }}</p>
<p>{{  poem.like  }} person likes this poem.</p>

<a href="/poems/like/{{  poem.id  }}" class="btn btn-success btn-large active"><i class="icon-white icon-heart"></i> Like it!</a>





<form method="post" action="/poems/comment/{{  poem.id  }}/">{% csrf_token %}

    <label for="title">Title</label>
    <p><input type="text" name="title" id="title"></p>
    <label for="text">Comment</label>
    <p><textarea id="text" name="text_of_comment" rows="7" cols="50"></textarea></p>
    <label for="nick">Nick</label>
    <p><input id="nick" name="nick" type="text"></p>
    <input type="submit" class="btn btn-success btn-large" value="OK"/>

</form>
{%  for comment in all_comments  %}
    <h5>{{  comment.title  }}</h5>
    <p>{{  comment.text  }}</p>
    <p>{{  comment.nick  }}</p>
{%  endfor  %}

{%  endblock  %}

首先:当我运行服务器并发表评论时,它会返回:

禁止(403)

CSRF验证失败。请求中止。

我不明白为什么,因为我的所有其他功能和模板都以相同的方式构建并正常工作。 我做错了什么?

第二:我在comment()函数中使用ForeignKey()的方式是否正确?这是在诗歌下创作评论的好方法吗?你们是如何解决这个问题的?

Thanx for anwsers:)

2 个答案:

答案 0 :(得分:1)

您可以尝试删除所有Cookie以解决您的CSRF问题(我过去也一样,并在删除我的Cookie后工作)

如果您没有嵌套评论,那么关于您的模型是可以的。

你没有问,但是我会给你一个关于你的代码的建议,对于URL使用反向,因为有一天如果你改变某些东西,你将不得不在任何地方修复......

https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls

答案 1 :(得分:0)

答案是:

comment()函数重定向到另一个函数:

    `return HttpResponseRedirect('/poems/get/%s' % poem_id, args)`

在该网址下的功能:'/poems/get/%s' % poem_id

应包含CSRF令牌。

应该是这样的:

def poem(request, poem_id = 1): args = {} poem = Poem.objects.get(id = poem_id) args['poem'] = poem all_comments = poem.comment_set.all() args['all_comments'] = all_comments args.update(csrf(request)) return render_to_response('poems/poem.html', args)

现在它没有禁止(403):)