Проблема с использованием i18n_patterns с API

У меня есть приложение, которое включает веб-сайт и API. Я перевел сайт на второй язык. В настоящее время основным языком является английский, а вторым - фарси. Я использовал i18n_patterns в urlpatterns для перенаправления между двумя языками. Проблема заключается в том, что при использовании API Django перенаправляет мой запрос, и, поскольку данные отправляются с использованием POST, он удаляет все данные и дает мне пустой результат с использованием GET. Я попытался взять URL-адрес API из шаблона URL-адреса, а затем добавить его, что решает эту проблему, но это не работает, поскольку мне нужна поддержка Unicode для фарси, и поскольку таким образом нет поддержки i18n_patterns, я получаю неразборчивый ответ.
Это URL-шаблон:

urlpatterns = i18n_patterns(
    path('admin/', admin.site.urls),
    path('mainapp/', include('mainapp.urls')),
    path('', include('mainapp.urls')),
    prefix_default_language=True
) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

urlpatterns.append(path('api/', include('mainapp.api.urls')))

Есть ли способ решить эту проблему с минимальными изменениями в приложении? Любая помощь, предложение или руководство будут очень признательны.

EDIT: Спасибо. Я изменил код, чтобы воспроизвести проблему. Я звоню http://localhost:8000/api/scan/. Если я добавлю path('api/', include('mainapp.api.urls')) к исходному шаблону URL-адреса с i18n_patterns и отправлю запрос в API, значение request.POST будет <QueryDict: {}>, в противном случае он должен отправить key:value на серверную часть. Я осмотрелся, и кажется, что когда вы добавляете i18n_patterns в шаблоны URL, происходит перенаправление, и, поскольку HTTP не разрешает перенаправление данных POST, я получаю пустой ответ.


person Saman Hamidi    schedule 04.12.2019    source источник
comment
Не понимаю, зачем редирект. Вы должны точно объяснить, по какому URL-адресу вы звоните, что вызывает перенаправление и на какой URL-адрес перенаправляется. Пожалуйста, используйте явные URL-адреса (путь/к чему-либо).   -  person dirkgroten    schedule 04.12.2019
comment
Спасибо. Я отредактировал свой ответ, чтобы лучше объяснить проблему.   -  person Saman Hamidi    schedule 04.12.2019
comment
Но вам вообще не следует отправлять запрос на /api/scan/, если вы ожидаете, что запросы будут отправлены на правильном языке. Вы должны отправить на <lang>/api/scan/, чтобы не получить перенаправление. В качестве альтернативы вы можете установить prefix_default_language на False, чтобы URL-адреса на английском языке не были префиксом, и, следовательно, запрос на /api/scan будет считаться английским и не перенаправляться.   -  person dirkgroten    schedule 04.12.2019
comment
Обратите внимание, что я также не понимаю, почему вы получаете неправильный ответ, если не используете переведенные шаблоны URL. Django не определяет язык только на основе шаблона URL, он определяет его на основе заголовков или файлов cookie, см. это. Если вам не нужно переводить ваши URL-адреса (а в API это редко имеет смысл делать), то я бы не стал включать свои URL-адреса API в i18n_patterns. Просто убедитесь, что запросы к вашему API содержат правильный HTTP-заголовок.   -  person dirkgroten    schedule 04.12.2019
comment
@dirkgroten Спасибо. Я понятия не имею, почему это происходит. Я даже не знаю, что искать. Однако, чтобы как-то обойти эту проблему, я изменил настройки своего шаблона URL-адреса на это: admin/', admin.site.urls), path('sslcheck/', include('sslcheck.urls')), path('', include('sslcheck.urls')), prefix_default_language=True, ) + static (settings.STATIC_URL, document_root=settings.STATIC_ROOT) ``` Теперь есть способ заставить API загружаться только на английском языке?   -  person Saman Hamidi    schedule 04.12.2019
comment
Вы должны прочитать страницу перевода, на которую я дал ссылку выше. Все это. Вы явно не понимаете, что должен делать i18n_patterns: это только перевод самого URL. Так, например, если у вас есть URL-адрес /shop/product/ на английском языке, и вы хотите, чтобы он был /magazin/produit/ на французском языке, чтобы ваши пользователи лучше понимали, где они находятся на сайте (когда они смотрят на адресную строку в своем браузере).   -  person dirkgroten    schedule 04.12.2019
comment
@dirkgroten Э-э. Спасибо. Я мог неправильно понять документы. Хотя я пытался их читать. Я очень новичок в программировании. Если вы поместите это в ответы. Я выберу это как правильное решение.   -  person Saman Hamidi    schedule 04.12.2019
comment
Удалите URL-адреса API из шаблонов i18n_patterns и исправьте исходную проблему, которую вы пытаетесь решить, а именно неразборчивый ответ. Установите заголовок HTTP для Accept-Language на фарси в вашем POST-запросе, и если у вас все еще есть неправильный ответ, отправьте новый вопрос по этому поводу, если вы застряли.   -  person dirkgroten    schedule 04.12.2019
comment
@dirkgroten Я взял URL-адрес API из i18n_patterns. Это решает проблему POST/GET. Хотя я все еще понимаю его на фарси, потому что в настройках языка по умолчанию стоит «фа». Мне нужно, чтобы сайт загружался на фарси, но не API.   -  person Saman Hamidi    schedule 04.12.2019
comment
Затем установите HTTP Accept-Language на английский для всех ваших запросов API. И убедитесь, что файл cookie не установлен (сначала он ищет файл cookie). Кроме того, вы можете вручную переопределить язык в своем коде для всех представлений API, если хотите, чтобы каждый, кто вызывает API, всегда получал английский язык.   -  person dirkgroten    schedule 04.12.2019
comment
@dirkgroten Большое спасибо за помощь. Я поищу эти. Надеюсь, я смогу это исправить. Я хотел бы принять ваш ответ, если вы поместите его как ответ.   -  person Saman Hamidi    schedule 04.12.2019


Ответы (2)


Целью i18n_patterns является перевод самого URL-адреса, поэтому немного странно, что вы хотите сделать это для API. Идея состоит в том, что пользователи, которые смотрят на адресную строку в своем браузере, читают URL-адреса, и это может помочь перевести их, чтобы им было легче понять, где они находятся на вашем сайте. Так, например, если у вас есть URL-адрес «/shop/product/» на английском языке, и вы хотите, чтобы он был «/magazin/produit/» на французском языке.

Поскольку API не отображает URL-адреса для конечных пользователей, просто не имеет смысла, чтобы URL-адреса API подпадали под i18n_patterns. Это решит проблему переадресации.

Ваша первоначальная проблема заключается в том, что ваше представление возвращает «неразборчивый ответ», когда вы вызываете его, используя URL-адрес, в котором не указан язык. Вероятно, это связано с тем, что представление определяет неправильный язык. вот как Django определяет языковые предпочтения. Поэтому, если URL-адрес не содержит информации, он будет:

  • Найдите языковой файл cookie.
  • Посмотрите на HTTP-заголовок Accept-Language в этом порядке.

Таким образом, вы можете либо убедиться, что ваши запросы API устанавливают правильный заголовок (и не отправлять языковой файл cookie), либо вы можете просто установить активный язык в каждом представлении, вызываемом API.

person dirkgroten    schedule 04.12.2019
comment
Огромное спасибо за помощь. Это сделало вещи намного яснее. - person Saman Hamidi; 04.12.2019

Не уверен, что полностью понимаю вашу проблему, но вы можете предотвратить перенаправления, установив redirect_on_fallback на False в настройках CMS_LANGUAGES.

person Christoph    schedule 04.12.2019