简体   繁体   中英

Django passing multiple variables in render

I am trying to pass multiple variables in Django render. One of them is the csrf token and the other one is my form (because I need the errors from the form) For some reason none of them work. Any help?

Here is the template :

<form class = "navbar-form" action="{% url "registry.views.register" %}" onsubmit=" return ClickButton();  " method= "POST" >
{% csrf_token %}
{{ form.errors}} {{ form.non_field_errors }} 

here is the view.py:

def register(request):

form_save = RegisterationForm()
if request.method == 'POST':
    form = RegisterationForm(request.POST)

    if form.is_valid():

        user_info={}
        user_info['username'] = form.cleaned_data['username']
        user_info['password'] = form.cleaned_data['password']


        form.save(user_info)
        return render_to_response('register_success.html',user_info)

    else:
        form_save = form


return render_to_response('register.html',{'csrf':csrf(request),'locals':locals()})

Why pass csrf manually? {% csrf_token %} does that automatically.

Also, if you are using any newer version of Django, you can use render() .

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

That should do it.

If you were not using the {} litteral dictionary, I'd suggest changing:

return render_to_response('register.html',{'csrf':csrf(request),'locals':locals()})

to use the ** to expand the locals()-returned dictionary into keywords. But that will probably not work.

return render_to_response('register.html',{'csrf':csrf(request),**locals()})

Try this instead:

my_dict = {csrf:csrf(request)}

my_dict.update(locals())

return render_to_response(
    'register.html',
    my_dict,

)

That said, probably cleaner to explicitly pass what you want, using the dict constructor:

return render_to_response(
    'register.html',
    dict(
        csrf=csrf(request),
        user_info=user_info,
        form=form,
    )

)

And the reason your template doesn't find say form is that it isn't there at in the context. The context has csrf and locals , where form resides. You could reference {{locals.form}} instead. But that's ugly.

You don't need to pass your csrf token, you can decorate your view function with @csrf_protect to pass the token to the current context. The form can be added to the context dictionary:

@csrf_protect
def your_view(request):
    # process request

    # add form to context dictionary, and return RequestContext for current request
    return render_to_response('register.html', {'form': form}, RequestContext(request))

Alternatively, you can do a site wide csrf protection by adding 'django.middleware.csrf.CsrfViewMiddleware' to your MIDDLEWARE_CLASSES (usually added by default). You should read more from the docs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM