1

render_to_string を使用する必要がありますが、使用できません

@csrf_protect

そして合格

context_instance=RequestContext(request)) 

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

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

「NoneType」オブジェクトには属性「COOKIES」がありません

編集:コメントをありがとう、ここにいくつかの説明があります:

「ポートレット」に似た「パネル」システムを作成しています。パネルはデータベースで構成されます (パネルを文字列としてレンダリングするための Python 関数の名前を含む - パネル関数は実行時に名前からインポートされます。データベース)。

これらのパネルをページに配置するために、DB から必要なパネルの名前を読み取り、それらを文字列としてレンダリングし、1 つの大きな html の塊を (文字列として) ページに返すカスタム テンプレート タグを作成しました。レンダリングされます。(これにより、ユーザーは表示するパネルを選択できます。)

私の問題は、パネルの 1 つ (render_to_string を使用してテンプレートを文字列としてレンダリングする単純な python 関数) にフォームがあることです。

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

4

4 に答える 4

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)

テンプレートには次のものが含まれています。

<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='{{ csrf_token_value }}'/></div>
于 2012-04-28T08:12:58.760 に答える
1

あなたの見解では request.COOKIES['csrftoken'] を使用します Cookie が常に利用可能かどうかわからないので、私の解決策はリクエストごとに 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)
于 2012-07-02T09:44:37.297 に答える
0

ビューは常にHttpResponse(またはその祖先の1つ)を返す必要があります。したがって、を返す必要がありますがHttpResponse(your_rendered_string)、を呼び出すのと同じrender_to_responseです。応答本文を変更する必要がある場合は、応答でも変更できます。

response = render_to_response(...)
response.content = response.content.replace('A', 'B')
return response
于 2012-04-28T04:57:54.343 に答える
0

完全なソリューションの例を次に示します。すべてこの優れた投稿から派生したものです。

これは、同じことを繰り返すことなく、サイトの複数のページに招待フォームを含めたいというシナリオに基づいています。

招待状.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 )

招待状ウィジェットテンプレート.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>

ビュー.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>
于 2013-04-05T19:32:49.193 に答える