我想创建一个非常简单的网站,每个人都可以发一首诗,每个人都可以评论其他诗歌。所以:模板上有一首诗,还有很多评论。我知道,有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:)
答案 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):)