Как управлять перенаправлением языков в промежуточном ПО Django с аутентификацией пользователей?
Я разрабатываю промежуточное ПО на Django для управления языковой переадресацией на основе языковых предпочтений пользователя, которые могут храниться в базе данных или указываться в cookie. Промежуточное ПО должно обрабатывать URL-адреса, включающие языковой префикс, обеспечивая их соответствие предпочтительному языку пользователя, особенно после того, как пользователь войдет в систему.
Промежуточное ПО предназначено для перенаправления пользователей на нужную языковую версию страницы. Однако, когда пользователь входит в систему и параметр next используется для указания URL-адреса перенаправления, префикс языка в этом URL-адресе иногда не совпадает с предпочитаемым языком пользователя. В результате пользователи перенаправляются на язык по умолчанию, а не на предпочитаемый язык.
Вот реализация промежуточного ПО:
from django.http import HttpResponseRedirect
from django.utils.http import urlencode
from urllib.parse import urlparse, urlunparse, parse_qs
from django.utils.translation import activate
class UserLanguageMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
excepted_paths = ["/stripe/", "/api/", "/media/", "/static/", "/set-language/"]
if any(request.path.startswith(path) for path in excepted_paths):
return response
preferred_language = None
if request.user.is_authenticated:
preferred_language = getattr(request.user, "language", None)
if not preferred_language:
preferred_language = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, "en")
activate(preferred_language)
current_cookie_language = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
if current_cookie_language != preferred_language:
response.set_cookie(
settings.LANGUAGE_COOKIE_NAME,
preferred_language,
max_age=365 * 24 * 60 * 60,
path="/",
)
current_full_path = request.get_full_path()
url = urlparse(current_full_path)
if preferred_language not in url.path:
query_params = parse_qs(url.query)
next_path = query_params.get('next', [None])[0]
if next_path:
next_url = urlparse(next_path)
if next_url.path[:3] in ("/en", "/sl", "/hr"):
next_path = f'/{preferred_language}{next_url.path[3:]}'
else:
next_path = f'/{preferred_language}{next_url.path}'
query_params['next'] = [next_path]
url = url._replace(query=urlencode(query_params, doseq=True))
modified_path = (
url.path[3:]
if url.path[:3] in ("/en", "/sl", "/hr")
else url.path
)
new_path = f"/{preferred_language}{modified_path}"
new_url = urlunparse(
(
url.scheme,
url.netloc,
new_path,
url.params,
urlencode(query_params, doseq=True),
url.fragment,
)
)
return HttpResponseRedirect(new_url)
return response
То, что я ожидал:
Я ожидал, что промежуточное ПО будет последовательно перенаправлять на URL-адреса, соответствующие предпочитаемому языку пользователя после входа в систему, особенно если используется параметр next. Цель состоит в том, чтобы языковой префикс URL и язык, указанный в следующем параметре, всегда соответствовали языковым предпочтениям пользователя.
Вопросы:
Как обеспечить точное отражение и сохранение языковых предпочтений в URL и следующем параметре во всех сценариях перенаправления, особенно после входа в систему? Есть ли лучший подход к изменению следующего параметра в промежуточном ПО для обеспечения согласованности языка?