簡體   English   中英

Django的。 如何發表評論? -最簡單的例子。 CSRF驗證失敗

[英]Django. How to make comments? - The simplest example. CSRF verification failed

我想創建一個非常簡單的網站,每個人都可以在其中發布一首詩,每個人都可以評論其他詩歌。 所以:模板上的一首詩,還有很多評論。 我知道,有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()的方式正確嗎? 用詩歌創作評論的好方法嗎? 你們如何解決這個問題?

感謝anwers :)

您可以嘗試刪除所有cookie來解決CSRF問題(我過去有過同樣的經歷,並且在刪除cookie后可以使用)

如果沒有嵌套注釋,關於模型的操作就可以了。

您沒有要求,但是我會為您的代碼提供建議,對URL使用反向,因為有一天如果您更改某些內容,則必須在任何地方進行修復...

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

答案是:

comment()函數重定向到另一個函數:

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

所以該URL下的功能: '/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):)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM