在这种情况下使用django render_to_response的正确方法?

时间:2013-07-28 18:19:46

标签: django render

基本上,在我的index.html模板中,我希望登录和注册表单相同(两者都有csrf_token)。这是我的观点。

def index(request):
    c = {}
    c.update(csrf(request))
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/accounts/register_success')

    args = {}
    args.update(csrf(request))

    args['form'] = MyRegistrationForm()

    return render_to_response('index.html', {c, form: args})

问题在于render_to_response语句。之前,我将索引视图视为两种不同的视图。

    c = {}
    c.update(csrf(request))
    return render_to_response('index.html', c)

是登录的返回声明和

    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/accounts/register_success')

    args = {}
    args.update(csrf(request))

    args['form'] = MyRegistrationForm()

    return render_to_response('register.html', args)

是注册表的退货声明。 (注册表单和index.html登录表单之前在两个不同的模板中。我试图将它们放在一个模板中。

这是我的index.html模板(两个表单都在同一个模板中)。

<form action="/accounts/auth/" method="post">{% csrf_token %}
    <label for="username">User name:</label>
    <input type="text" name="username" value="" id="username">
    <label for="password">Password:</label>
    <input type="password" name="password" value="" id="password">

    <input type="submit" value="login" />

</form>
<h2>Register</h2>
<form action="/accounts/register/" method="post">{% csrf_token %}
    {{form}}

    <input type="submit" value="Register" />

</form>

1 个答案:

答案 0 :(得分:3)

你没有解释你的问题是什么,但我发现一件重大事情立刻就出现了问题。

render_to_response期望其上下文参数的字典。您提供的值{c, form: args}不是字典。

在最新版本的Django上,您通常希望使用render而不是render_to_response。它完成render_to_response所做的一切,并使用RequestContext对象,以便上下文处理器正常工作。这对csrf处理特别有用。正如docs所说:

  

在相应的视图函数中,确保正在使用'django.core.context_processors.csrf'上下文处理器。通常,这可以通过以下两种方式之一完成:

     
      
  1. 使用RequestContext,它始终使用'django.core.context_processors.csrf'(无论您的TEMPLATE_CONTEXT_PROCESSORS设置如何)。

  2.   
  3. 手动导入并使用处理器生成CSRF令牌并将其添加到模板上下文中。

  4.   

总的来说,我会重新审视你的观点:

def index(request):
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/accounts/register_success')
    else:
        form = MyRegistrationForm()

    return render(request, 'index.html', {form: form})

只是为了演示如何在没有RequestContext的情况下执行此操作:

def index(request):
    c = {}
    c.update(csrf(request))
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/accounts/register_success')
    else:
        form = MyRegistrationForm()
    c['form'] = form
    return render_to_response('register.html', c)

重点是将表单和csrf标记放入字典中。

使用redirect快捷方式和视图名称而非固定网址确定重定向目标通常是一种很好的做法。