2017-06-06 3 views
0

Ich versuche, ein benutzerdefiniertes Template-Tag zu erstellen, um einen Kommentar anzuzeigen. Wenn ich versuche, eine Antwort über das Formular zu jedem Kommentar zu senden, erhalte ich eine Fehlermeldung:Vorlagen-Tag funktioniert nicht mit csrf_token

Forbidden (403) CSRF-Überprüfung fehlgeschlagen. Anfrage abgebrochen. Grund für Fehler angegeben: CSRF-Token fehlt oder ist falsch.

Das csrf-Token funktioniert auf dem Formular mit der Download- und der Folgen-Schaltfläche, aber nicht mit dem Formular, das aus dem Vorlagen-Tag generiert wird. Jede Hilfe wäre willkommen.

Document

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> 

Antwort

1

Da Sie die Vorlage manuell in Ihrem Tag rendern, müssen Sie RequestContext verwenden, damit die Kontextprozessoren ausgeführt werden - einschließlich der, die das CSRF-Token hinzufügt.

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

Hinweis, die ganze Sache könnte stark vereinfacht werden mit einem inclusion tag.

+0

Wenn ich das mache, bekomme ich diesen Fehler: Kontext muss ein Diktat sein, anstatt RequestContext. – user1637466

+2

Versuchen Sie 't.render ({...}, request = context ['request'])' stattdessen. – Alasdair

+1

Ja, die Dokumentation ist verwirrend; Die Template-Klasse, die Sie von get_template erhalten, ist nicht dieselbe, die Sie erhalten, wenn Sie eine Vorlage direkt instanziieren. –

Verwandte Themen