Django调用外部API时自动添加请求头的方案咨询
嘿,这个问题我之前帮不少开发者踩过坑——Django中间件确实只管进入你应用的请求,对外发起的请求它可插不上手。不过有几个实用的方案,帮你统一处理外部请求的头,不用每次手动加:
方案1:封装自定义API客户端类
这是最灵活可控的方式,把所有外部API请求都收拢到一个工具类里,让它自动帮你注入请求头。举个简单的实现例子:
import requests from django.conf import settings class ExternalAPIClient: def __init__(self): # 从配置里读取固定请求头,也可以根据需求动态生成 self.base_headers = { 'Authorization': f'Bearer {settings.EXTERNAL_API_AUTH_TOKEN}', 'Content-Type': 'application/json' } def get(self, url, params=None, extra_headers=None): # 合并基础头和额外头,额外头会覆盖重复的键 final_headers = {**self.base_headers, **(extra_headers or {})} return requests.get(url, params=params, headers=final_headers) def post(self, url, json=None, extra_headers=None): final_headers = {**self.base_headers, **(extra_headers or {})} return requests.post(url, json=json, headers=final_headers) # 调用示例:在视图、任务里都能用 client = ExternalAPIClient() response = client.get('https://api.example.com/user/list') # 特殊请求加额外头也很方便 response = client.post('https://api.example.com/user/create', json={"name": "John"}, extra_headers={"X-Request-ID": "123"})
这种方式的好处是,所有外部请求的逻辑都集中在一处,后续要改请求头规则(比如加新的头、更新token逻辑),只需要改这个类就行。
方案2:用requests的Session对象持久化请求头
如果你平时用requests库,它的Session对象可以帮你一次性设置好请求头,后续所有通过这个Session发起的请求都会自动带上这些头:
import requests from django.conf import settings # 可以在项目初始化时创建全局Session(比如在app的apps.py的ready方法里) external_api_session = requests.Session() external_api_session.headers.update({ 'Authorization': f'Bearer {settings.EXTERNAL_API_AUTH_TOKEN}', 'Accept': 'application/json' }) # 调用时直接用这个Session response = external_api_session.get('https://api.example.com/data') # 个别请求需要额外头,直接传即可,会和Session里的头合并 response = external_api_session.post('https://api.example.com/submit', headers={"X-Custom-Header": "my-value"})
这个方案比写类更简洁,适合请求头大部分固定、不需要复杂逻辑的场景。
方案3:异步场景用aiohttp的ClientSession
如果你的项目用了Django的异步视图或者异步任务(比如Celery异步),那用aiohttp的ClientSession更合适,原理和requests的Session类似:
import aiohttp from django.conf import settings async def fetch_external_data(): async with aiohttp.ClientSession(headers={ 'Authorization': f'Bearer {settings.EXTERNAL_API_AUTH_TOKEN}', 'Content-Type': 'application/json' }) as session: async with session.get('https://api.example.com/async-data') as response: return await response.json()
小提醒
- 敏感的API密钥别硬编码,用Django的
settings或者环境变量存储(可以配合python-dotenv包管理环境变量)。 - 如果请求头需要动态生成(比如每次请求要刷新临时token),可以在客户端类的方法里加前置逻辑,比如每次发起请求前先获取最新token,再组装请求头。
内容的提问来源于stack exchange,提问作者erick.chali
相关产品推荐
相关产品推荐

