# python: Пользовательское определение локали
URL: https://generaltranslation.com/ru/docs/python/tutorials/custom-locale-detection.mdx
---
title: Пользовательское определение локали
description: Как настроить определение локали с помощью get_locale и как работает поведение по умолчанию
---
## Поведение по умолчанию
Если в [`initialize_gt`](/docs/python/api/initialize-gt) не передана callback-функция `get_locale`, GT автоматически определяет локаль пользователя по HTTP-заголовку `Accept-Language` при каждом запросе:
1. Считывает заголовок `Accept-Language` (например, `en-US,en;q=0.9,es;q=0.8`)
2. Преобразует его в список локалей, отсортированных по значению качества (от большего к меньшему)
3. Сопоставляет их с настроенными у вас `locales`, чтобы найти наиболее подходящую
4. Если совпадение не найдено, использует `default_locale`
Это значит, что «из коробки» пользователи получают контент на языке, который запрашивает их браузер, — при условии, что у вас есть для него переводы.
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
# Без get_locale — по умолчанию используется разбор Accept-Language
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
)
```
```python
from fastapi import FastAPI
from gt_fastapi import initialize_gt
app = FastAPI()
# Без get_locale — по умолчанию используется разбор Accept-Language
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
)
```
***
## Пользовательская `get_locale`
Чтобы переопределить поведение по умолчанию, передайте callback-функцию `get_locale` в `initialize_gt`. Она получает объект запроса и должна возвращать строку локали.
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
def get_locale(request) -> str:
# Сначала проверяем параметр запроса
locale = request.args.get("lang")
if locale:
return locale
# Затем проверяем cookie
locale = request.cookies.get("locale")
if locale:
return locale
# Если ничего не найдено, используем значение по умолчанию
return "en"
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
get_locale=get_locale,
)
```
```python
from fastapi import FastAPI, Request
from gt_fastapi import initialize_gt
app = FastAPI()
def get_locale(request: Request) -> str:
# Сначала проверяем параметр запроса
locale = request.query_params.get("lang")
if locale:
return locale
# Затем проверяем cookie
locale = request.cookies.get("locale")
if locale:
return locale
# Если ничего не найдено, используем значение по умолчанию
return "en"
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
get_locale=get_locale,
)
```
***
## Как это устроено внутри
* **FastAPI**: `initialize_gt` регистрирует HTTP middleware, которое выполняется при каждом запросе. Если указан `get_locale`, вызывается `get_locale(request)`. В противном случае разбирается заголовок `Accept-Language`. Определённая локаль устанавливается в `I18nManager`, откуда её считывает [`t()`](/docs/python/api/t).
* **Flask**: `initialize_gt` регистрирует хук `before_request` с той же логикой.
***
## Типовые паттерны
### Префикс в пути URL
Извлеките локаль из URL-пути (например, `/es/about`, `/fr/home`):
```python
def get_locale(request) -> str:
parts = request.url.path.strip("/").split("/")
supported = {"es", "fr", "de"}
if parts and parts[0] in supported:
return parts[0]
return "en"
```
### Профиль пользователя
Определите локаль по предпочтениям аутентифицированного пользователя:
```python
def get_locale(request) -> str:
user = get_current_user(request) # ваша логика аутентификации
if user and user.preferred_locale:
return user.preferred_locale
return "en"
```
### Поддомен
Определяйте локаль по поддомену, например `es.example.com`:
```python
def get_locale(request) -> str:
host = request.headers.get("host", "")
subdomain = host.split(".")[0]
if subdomain in ("es", "fr", "de"):
return subdomain
return "en"
```
***
## Примечания
* Ваша функция `get_locale` всегда должна возвращать корректную строку локали
* Если она возвращает локаль, для которой у вас нет переводов, `t()` вернёт исходное содержимое из `default_locale`
* Функция получает исходный объект запроса фреймворка — `Request` для FastAPI, `request` из Flask для Flask
* Вы можете использовать [`get_locale()`](/docs/python/api/get-locale) в других частях кода, чтобы получить определённую локаль