2017-06-06 52 views
0

我正在尝试创建自定义模板标记以显示评论。当我尝试通过每条评论附带的表单提交答复时,出现错误:模板标记不与csrf_token一起使用

禁止(403) CSRF验证失败。请求中止。 失败的原因: CSRF令牌丢失或不正确。

csrf标记在窗体上使用下载和关注按钮,但不在从模板标记生成的窗体上。任何帮助,将不胜感激。

DocumentView

def DocumentView(request, doc_id): 
    context = {} 
    user = None 
    if request.user.is_authenticated(): 
     email = request.user.email 
     id = request.user.id 
     user = get_user_information(email=email) 
    else: 
     user = None 

    context['user'] = user 

    if request.method == 'POST': 
     user_id = request.POST.get('submit', '') 


    doc = Doc.objects.get(id=doc_id) 
    doc_version = DocVersion.objects.filter(doc__id=doc_id).latest('id') 
    doc_title = doc.response_title 
    allow_comments = doc.allow_comments 
    comments = {} 
    if user['user_type'] == 'DA': 
     for comment in Comment.objects.filter(doc_id=doc_id): 
      comments[comment.id] = {'content': comment.content, 'reply_to': comment.reply_to, 'user_id': comment.user.id} 
    else: 
     for comment in Comment.objects.filter(doc_id=doc_id, is_flagged=False): 
      comments[comment.id] = {'content': comment.content, 'reply_to': comment.reply_to, 'user_id': comment.user.id} 
    context['comments'] = comments 
    context['allow_comments'] = allow_comments 
    context['doc_title'] = doc_title 
    print context 
    return render(request, 'doc/document.html', context) 

comment_tags.py

from django.template import Library, Node, Context, Variable 
from django.template.loader import get_template 
from django import template 

register = Library() 

@register.tag() 
def comments(parser, token): 
    user_id, profile_pic, reply_id, comment_id, content, info = None, None, None, None, "", "" 

    for index, x in enumerate(token.split_contents()): 
     if x == 'user_id': 
      user_id = token.split_contents()[index + 1] 
     if x == 'profile_pic': 
      profile_pic = token.split_contents()[index + 1] 
     if x == 'content': 
      content = token.split_contents()[index + 1] 
     if x == 'info': 
      info = token.split_contents()[index + 1] 
     if x == 'reply_id': 
      reply_id = token.split_contents()[index + 1] 
     if x == 'comment_id': 
      comment_id = token.split_contents()[index + 1] 

    return CommentNode(user_id, profile_pic, comment_id, content, info, reply_id) 




class CommentNode(template.Node): 
    def __init__(self, user_id, profile_pic, comment_id, content, info, reply_id): 
     self.user_id = template.Variable(user_id) 
     self.profile_pic = template.Variable(profile_pic) 
     self.content = template.Variable(content) 
     self.info = template.Variable(info) 
     self.comment_id = template.Variable(comment_id) 

     if reply_id != None: 
      self.reply_id = template.Variable(reply_id) 
     else: 
      self.reply_id = reply_id 

    def render(self, context): 
     t = get_template("srd/comment.html") 

     if self.reply_id == None: 
      return t.render({ 
        'user_id': self.user_id.resolve(context), 
        'profile_pic': self.profile_pic.resolve(context), 
        'comment_id': self.comment_id.resolve(context), 
        'content': self.content.resolve(context), 
        'info': self.info.resolve(context), 
        'reply_id': self.reply_id 
       } 
      ) 
     else: 
      return t.render({ 
       'user_id': self.user_id.resolve(context), 
       'profile_pic': self.profile_pic.resolve(context), 
       'comment_id': self.comment_id.resolve(context), 
       'content': self.content.resolve(context), 
       'info': self.info.resolve(context), 
       'reply_id': self.reply_id.resolve(context) 
      }) 

document.html

{% load static %} 
{% load comment_tags %} 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>{{ doc_title }}</title> 
    <link rel="stylesheet" type="text/css" href="{% static "stylesheets/doc.css" %}"> 
    <script src="{% static "javascript/jquery-3.2.1.min.js" %}" type="text/javascript"></script> 
    <script src="{% static "javascript/doc.js" %}" type="text/javascript"></script> 

</head> 
<body> 
    <div class="main_div"> 
     <div class="content_div"> 
      <div class="info_div"> 
       <h2>[{{ generic_name }}]</h2> 
       <label>{{ doc_title }} <a href="edit">[Edit]</a></label> 

      </div> 
      <div class="doc_div"> 
       <div class="doc_preview"> 
       </div> 
       <div class="doc_preview_info"> 
        <form method="post"> 
         {% csrf_token %} 
         <input type="hidden" value="{{ user.id }}" /> 
         <input type="submit" value="Donwload PDF" /><br/> 
         <input type="submit" value="Follow" /> 
        </form> 

       </div> 
      </div> 
      {% if allow_comments %} 
      <div class="comment_div" id="comment_div"> 
       {% for commentid, comment in comments.items %} 
        {% if comment.reply_to %} 
         {% comments comment_id commentid user_id comment.user_id reply_id comment.reply_to.id profile_pic "hi" content comment.content info "XYZ" %} 
        {% else %} 
         {% comments comment_id commentid user_id comment.user_id profile_pic "hi" content comment.content info "XYZ" %} 
        {% endif %} 
       {% endfor %} 
      </div> 
      {% endif %} 
     </div> 
     <div class="ad_div"> 
      <div class="ad"></div> 
      <div class="ad"></div> 
      <div class="ad"></div> 
      <div class="ad"></div> 
     </div> 
    </div> 
</body> 
</html> 

comment.html

<div class="comment"> 
    <div class="profile_pic"> 
    {{ user_id }} 
    </div> 
    <div class="comment_content"> 
     <div class="top_bar"> 
      <div class="comment_info"> 
       {{ info }} 
      </div> 
      <div class="flag"> 
       <a href="#">Flag</a> 
      </div> 
     </div> 
     <div class="comment_text"> 
      {{ content }} 
     </div> 
     <div class="reply_bar"> 
      <a id="reply_link_{{ comment_id }}" class="reply_link" href="#">Reply</a> 
     </div> 
    </div> 
</div> 
<div class="reply" id="reply_{{ comment_id }}"> 
    <form method="post"> 
     {% csrf_token %} 
     <input type="hidden" value="{{ reply_id }}"/> 
     <input name="reply_text" type="text" /> 
     <input type="submit" value="Post" /> 
    </form> 
</div> 

回答

1

由于您在标记中手动呈现模板,因此需要使用RequestContext,以便它运行上下文处理器 - 包括添加CSRF令牌的处理器。

return t.render(RequestContext(context['request'], { 
        ... 
       })) 

请注意,整个事情可以通过使用inclusion tag大大简化。

+0

当我这样做时,我得到这个错误: 上下文必须是一个字典,而不是RequestContext。 – user1637466

+2

尝试't.render({...},request = context ['request'])''。 – Alasdair

+1

是的,文档很混乱;从get_template获得的Template类与通过直接实例化模板所获得的Template类不同。 –

相关问题