Hi I have django internationalization working on my django site. That is if i browse ".../en/foo/bar" and ".../nb/foo/bar" they work fine. But i am trying to get a drop down menu to automatically change the language but i get csrf error.
base.html
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}"/>
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"
{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go"/>
</form>
I however have another form in the same html but I do not but {% csrf_token %} in it. I rather place
@csrf_exempt` on the view that handles the form.
I dont know whether having both froms on on html is what is causing the problem.
So what id did was that i created my own set_language view just like in django.veiws.i18n and places the @csrf_exempt
on it.
@csrf_exempt
def set_language(request):
"""
Redirect to a given url while setting the chosen language in the
session or cookie. The url and the language code need to be
specified in the request parameters.
Since this view changes how the user will see the rest of the site, it must
only be accessed as a POST request. If called as a GET request, it will
redirect to the page in the request (the 'next' parameter) without changing
any state.
"""
print 'I am in setlang'
next = request.POST.get('next', request.GET.get('next'))
if not is_safe_url(url=next, host=request.get_host()):
print 'not safe'
next = request.META.get('HTTP_REFERER')
if not is_safe_url(url=next, host=request.get_host()):
next = '/'
response = http.HttpResponseRedirect(next)
if request.method == 'POST':
lang_code = request.POST.get('language', None)
if lang_code and check_for_language(lang_code):
if hasattr(request, 'session'):
request.session[LANGUAGE_SESSION_KEY] = lang_code
else:
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN)
return response
Though the CSRF validation error is solved the form has no effect when i change the language and submit. it just stays on the same page. it appears that if not is_safe_url(url=next, host=request.get_host())
is always true. I am not sure what i am doing wrong now
I just realised that my form sends a GET request to the view instead of a post so request.method is GET
how and why is this so? The form data does not get to the view at all in this case but they submit when i leave the action attribute of the form blank. The the form submits to the view that called the page. Submitting to a specific view is not working as the request somehow becomes a get request
{% csrf_token %}
must be on every form. – itzMEonTV{% csrf_token %}
on both forms – flexxxitprint 'I am in setlang
andprint 'not safe
. `not safe' is always printed when i submit the form and next is also always empty (none) – flexxxit