2012-04-27 18 views
1

は私がrender_to_stringを使用する必要があるが、私はrender_to_stringを使用しているときに{%csrf_token%}を埋め込みますか?

@csrf_protect 

を使用して、私はデコレータはHttpResponseに、ないSafeStringを期待していると思うのでrender_to_stringする

context_instance=RequestContext(request)) 

を渡すことはできません。

私の文字列のフォームにcsrf_tokenを取得するにはどうすればよいですか?

「NoneType」オブジェクト持っていない属性「クッキー」

編集:

私は「パネル」システムを作成しています、ポートレット」に似て:コメントのおかげで、ここでいくつかの明確化です'で、パネルをデータベースで設定します(パネルを文字列としてレンダリングするPython関数の名前を含みます - パネル関数は実行時にデータベース内の名前からインポートされます)。

これらのパネルをページに入れるために、カスタムテンプレートタグを作成しました。これは、DBから必要なパネルの名前を読み込み、文字列をレンダリングし、htmlの大きなblob(文字列として)レンダリング中のページに移動します。

私の問題は、render_to_stringを使ってテンプレートを文字列としてレンダリングする単純なpython関数の1つが、その中にフォームを持っていることです。

文字列としてレンダリングされるので、CSRFフィールドをそのフォームに挿入する必要があります。

+4

私は何をやっている視覚化することができません。コードを表示する。 –

+2

あなたが望む解決策ではない問題を記述すると、助けが簡単になります。 –

答えて

5

私はこの問題を回避しましたが、まだまだ良い解決策があります。

パネル機能は、今のようになります。テンプレートは、今含んでいるが

def render_to_s(request, *args, **kwargs): 
    panelDisplays = PanelDisplay.listAll() 
    csrf_token_value = request.COOKIES['csrftoken'] 

    c = {"panelDisplays": panelDisplays, "csrf_token_value": csrf_token_value} 
    return render_to_string('panels/config.html', c) 

あなたがrequest.COOKIESを使用し、あなたのビューで
<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='{{ csrf_token_value }}'/></div> 
0

ビューは常にHttpResponse(またはその1つは祖先)を返す必要があります。したがって、HttpResponse(your_rendered_string)を返す必要がありますが、これはrender_to_responseと同じです。レスポンス本文を変更する必要がある場合は、レスポンスでも行うことができます。

response = render_to_response(...) 
response.content = response.content.replace('A', 'B') 
return response 
+0

ありがとうございますが、私はビューについては言及していません、私はrender_to_stringを使用しています。カスタムテンプレートタグ内から呼び出されています。 – fadedbee

1

を[ 'csrftoken'] 私はわからないんだけどクッキーが常に利用可能な場合、私のソリューションは各リクエストでcsrfトークンを生成することです。

from django.middleware.csrf import get_token 

def render_to_s(request, *args, **kwargs): 
    panelDisplays = PanelDisplay.listAll() 
    csrf_token_value = get_token(self.request) 

    c = {"panelDisplays": panelDisplays, "csrf_token_value": csrf_token_value} 
    return render_to_string('panels/config.html', c) 
0

以下は完全な解決策の例です。すべてこの優れた投稿から派生したものです。

これは、自分自身を繰り返すことなく、サイトの複数のページに招待状を含める場合に基づいています。

invitations.widgets。PY:

from invitations.forms import InvitationForm 
from django.middleware.csrf import get_token 
from django.template.loader import render_to_string 

def invitation_widget_function (request): 
    # ... blah blah blah 
    # ... stuff I don't want 
    # ... to repeat in every view 
    invitation_form = InvitationForm() 
    csrf_token_value = get_token(request) 
    context = { 'invitation_form': invitation_form, 
       'csrf_token_value': csrf_token_value } 
    return render_to_string ('invitation_widget_template.html', context) 

invitation_widget_template.html:

<form action="/whatever/" method="post"> 
    {% csrf_token %} {# don't do this because it won't work in streamed output #} 
    {# do this instead: #} 
    <div style='display:none'> 
    <input type='hidden' name='csrfmiddlewaretoken value='{{ csrf_token_value }}'/> 
    </div> 
    {{ invitation_form }} 
    <button type="submit">Invite Someone</button> 
</form> 

views.py:

from invitations.widgets import invitation_widget_function 
from django.shortcuts import render   

def page_view (request): 
    invitation_widget = invitation_widget_function(request) 
    context = { 'invitation_widget': invitation_widget } 
    return render (request, 'page_template.html', context) 

page_template.html:

<body> 
    <div> 
    {% include "some_normal_template.html" %} {# takes context from page_view() #} 

    {{ invitation_widget }} {# not an include, but a fully rendered string #} 
    {# took context from invitation_widget_function() -- has csrf token included #} 
    </div> 
</body> 
関連する問題