3

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()})

3 Answers 3

7

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.