2012-04-27 2 views
1

나는 render_to_string를 사용해야합니다,하지만 난render_to_string을 사용할 때 {% csrf_token %}을 채우시겠습니까?

@csrf_protect 

를 사용하고 난이 장식은 HttpResponse에 아닌 SafeString을 기대하고 있다고 생각하기 때문에

context_instance=RequestContext(request)) 

이 render_to_string을 전달할 수 없습니다.

내 문자열의 양식에 csrf_token을 가져 오는 방법은 무엇입니까?

'NoneType'개체가없는 속성 '쿠키'

편집 :

나는 '패널'시스템을 구축하고, 포틀릿 '과 비슷한 의견을 주셔서 감사합니다, 여기에 몇 가지 설명입니다 ', 여기서 패널은 데이터베이스에서 구성됩니다 (패널을 문자열로 렌더링하는 파이썬 함수의 이름 포함 - 패널 함수는 런타임시 해당 이름의 데이터베이스에서 가져옵니다).

이러한 패널을 페이지에 넣기 위해 DB에서 필요한 패널의 이름을 읽고 문자열을 렌더링 한 다음 html의 큰 blob (문자열)을 반환하는 사용자 지정 템플릿 태그를 만들었습니다. 렌더링되는 페이지로 이동합니다. (이것으로 사용자는 어떤 판넬이 표시 될지 선택할 수 있습니다.) 어떤 문제가 패널 (렌더링을위한 문자열을 렌더링하기 위해 render_to_string을 사용하는 간단한 파이썬 함수)에 형태가 있습니다.

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) 

동안 :보기에

<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='{{ csrf_token_value }}'/></div> 
0

조회수는 항상 HttpResponse (또는 그 중 하나는 조상)를 반환해야합니다. 따라서 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

당신이 request.COOKIES 사용 [ '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.평 :

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> 
관련 문제