# python: ロケール検出とミドルウェア
URL: https://generaltranslation.com/ja/docs/python/guides/middleware.mdx
---
title: ロケール検出とミドルウェア
description: Flask と FastAPI でロケール検出がどのように機能するか、およびそのカスタマイズ方法
---
GT の Python ミドルウェアは、リクエストごとにユーザーのロケールを自動的に検出し、それを [`t()`](/docs/python/api/t) と [`get_locale()`](/docs/python/api/get-locale) で利用できるようにします。このガイドでは、検出の仕組みと、カスタマイズのための高度なパターンを扱います。
カスタムロケール検出の基本的な内容については、[カスタムロケール検出チュートリアル](/docs/python/tutorials/custom-locale-detection)を参照してください。このガイドでは、それらのパターンをさらに掘り下げて説明します。
## デフォルトの挙動
`get_locale` コールバック関数が指定されていない場合、GT は `Accept-Language` ヘッダーを解析し、設定された `locales` と照合して、一致しない場合は `default_locale` を使用します。
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
initialize_gt(app, default_locale='en', locales=['es', 'fr'])
```
```python
from fastapi import FastAPI
from gt_fastapi import initialize_gt
app = FastAPI()
initialize_gt(app, default_locale='en', locales=['es', 'fr'])
```
## 検出戦略を組み合わせる
本番環境では通常、優先順位に沿って複数のソースを順に試します。`initialize_gt` に `get_locale` コールバックを渡してください。
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
def get_locale(request) -> str:
# 1. 明示的なクエリパラメーター
lang = request.args.get('lang')
if lang:
return lang
# 2. クッキー(ユーザーが保存した設定)
locale = request.cookies.get('locale')
if locale:
return locale
# 3. URL パスのプレフィックス (/es/about)
parts = request.path.strip('/').split('/')
if parts and parts[0] in ('es', 'fr', 'de'):
return parts[0]
# 4. Accept-Language ヘッダー
accept = request.headers.get('Accept-Language', '')
if accept:
return accept.split(',')[0].split(';')[0].strip()
return 'en'
initialize_gt(app, default_locale='en', locales=['es', 'fr', 'de'], get_locale=get_locale)
```
```python
from fastapi import FastAPI, Request
from gt_fastapi import initialize_gt
app = FastAPI()
def get_locale(request: Request) -> str:
# 1. 明示的なクエリパラメーター
lang = request.query_params.get('lang')
if lang:
return lang
# 2. クッキー(ユーザーが保存した設定)
locale = request.cookies.get('locale')
if locale:
return locale
# 3. URL パスのプレフィックス (/es/about)
parts = request.url.path.strip('/').split('/')
if parts and parts[0] in ('es', 'fr', 'de'):
return parts[0]
# 4. Accept-Language ヘッダー
accept = request.headers.get('accept-language', '')
if accept:
return accept.split(',')[0].split(';')[0].strip()
return 'en'
initialize_gt(app, default_locale='en', locales=['es', 'fr', 'de'], get_locale=get_locale)
```
## クッキーでロケールを保持する
ユーザーが言語を選択できるようにし、その選択を記憶します:
```python
from flask import request, make_response, jsonify
@app.route('/api/set-language', methods=['POST'])
def set_language():
locale = request.json.get('locale', 'en')
response = make_response(jsonify({'ok': True}))
response.set_cookie('locale', locale, max_age=365 * 24 * 60 * 60)
return response
```
```python
from fastapi import Request
from fastapi.responses import JSONResponse
@app.post('/api/set-language')
async def set_language(request: Request):
body = await request.json()
locale = body.get('locale', 'en')
response = JSONResponse({'ok': True})
response.set_cookie('locale', locale, max_age=365 * 24 * 60 * 60)
return response
```
## ユーザープロファイルに基づく検出
認証済みアプリでは、ユーザー設定からロケールを取得します。
```python
def get_locale(request) -> str:
user = get_current_user(request) # 認証ロジック
if user and user.preferred_locale:
return user.preferred_locale
# クッキーまたはヘッダーにフォールバック
return request.cookies.get('locale') or 'en'
```
## 最終的に決定されたロケールを確認する
リクエスト処理中の任意の場所で [`get_locale()`](/docs/python/api/get-locale) を使用すると、最終的に決定されたロケールを取得できます:
```python
from gt_flask import get_locale # または gt_fastapi
@app.route('/api/info')
def info():
return { 'locale': get_locale() }
```
## 次のステップ
* [カスタムロケール検出チュートリアル](/docs/python/tutorials/custom-locale-detection) — 基本的な紹介
* [`get_locale()` API リファレンス](/docs/python/api/get-locale)
* [文字列翻訳パターン](/docs/python/guides/strings) — コンテンツの翻訳方法