2015-08-28 7 views
0

Привет, у меня есть интернационализация django, работающая на моем сайте django. То есть, если я просматриваю «.../en/foo/bar» и «.../nb/foo/bar», они работают нормально. Но я пытаюсь получить раскрывающееся меню для автоматического изменения языка, но я получаю ошибку csrf.Ошибка CSRF django 1.8 i18n интернационализация

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> 

Я, однако, имеют другую форму в том же HTML, но я не но {% csrf_token %} in it. I rather place @ csrf_exempt` на представлении, который обрабатывает форму. Я не знаю, является ли причиной того, что оба из on on html являются причиной проблемы.

Так что же я сделал, что создал собственный вид set_language, как в django.veiws.i18n, и разместил на нем @csrf_exempt.

@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 

Несмотря на то, что ошибка проверки CSRF решена, форма не имеет никакого эффекта, когда я меняю язык и отправляю. он просто остается на одной странице. что if not is_safe_url(url=next, host=request.get_host()) всегда верно. Я не уверен, что я делаю неправильно сейчас

Я только что понял, что моя форма отправляет запрос GET на представление вместо сообщения, так что request.method: GET как и почему это так? Данные формы не попадают в представление вообще в этом случае, но они отправляются, когда я оставляю атрибут действия формы пустой. Форма отправляет представление, которое называется страницей. Отправка на конкретное представление не работает, так как запрос каким-то образом становится запросом получения

+0

'{% csrf_token%}' должно быть в каждой форме. – itzMEonTV

+0

Уверен, что это ваше мнение, которое называется, а не из библиотеки? – e4c5

+0

@itzmeontv yeah У меня есть '{% csrf_token%}' в обеих формах – flexxxit

ответ

0

С первой проблемой - ошибкой csrf нет простого решения (если вы хотите, чтобы csrf работал, а не обходил), потому что мы не можем сказать, что такое здесь происходит - может быть, проблема, связанная с печеньем.

Но вторая проблема проста в решении. В джанго есть bug. Простыми словами, django не будет переводить URL-адрес (префикс перед URL-адресом или переводить весь URL-адрес), когда пользователь меняет язык, поэтому пользователь будет перенаправлен на старый, а не переведенный URL-адрес с префиксом старого языка. Это приведет к возврату на старый язык после перенаправления.

Решение этой проблемы уже отправлено в django и будет доступно в django 1.9, но вы можете получить код этого вида из github и поместить его вместо текущего представления переключения языка.

Here - полная фиксация для этого исправления. В urlresolvers есть новая функция, называемая translate_url, которая используется в фиксированном виде.

Смежные вопросы