You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Apache通过mod_wsgi传递环境变量至Django 1.11配置

Fixing Apache SetEnv Environment Variables in Django 1.11

I've run into this exact issue with Django 1.11 before—your existing solutions aren't working because Django loads your settings module before your WSGI callback has a chance to set the environment variables. Let's break down why your current code fails, then fix it properly.

Why Your Current Solutions Aren't Working

Both of your approaches set os.environ variables after Django has already initialized:

  • 方案一: You call get_wsgi_application() first, which immediately loads your settings.py and runs all its top-level code. By the time you set os.environ in the application function, your settings have already been evaluated with the old (missing) environment values.
  • 方案二: django.setup() triggers the same settings load before your custom WSGIEnvironment class gets to process the request. The environment variables are set too late.

The Correct Django 1.11-Compatible Solution

We need to sync Apache's environ variables to os.environ BEFORE Django loads your settings. Here's how to modify your wsgi.py:

import os
from django.core.wsgi import get_wsgi_application

# List all environment variables you need from Apache SetEnv
REQUIRED_ENV_VARS = ["KEY", "DB_HOST", "DB_NAME", "DB_USER", "DB_PASSWORD"]

# Initialize the Django application only once
_application = None

def application(environ, start_response):
    global _application
    
    # Sync Apache's environment variables to os.environ FIRST
    for var_name in REQUIRED_ENV_VARS:
        if var_name in environ:
            os.environ[var_name] = environ[var_name]
    
    # Initialize Django only on the first request
    if _application is None:
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apiClient.settings")
        _application = get_wsgi_application()
    
    return _application(environ, start_response)

How This Works:

  1. First Request: When the first request hits your server, we first copy all required variables from Apache's environ into os.environ. Then we initialize Django's WSGI application, which loads your settings.py—now the settings can read the newly set environment variables.
  2. Subsequent Requests: The _application variable is already initialized, so we skip the setup step and just pass the request through. Since os.environ is process-wide, the variables stay set for all future requests.

Update Your Settings.py

Modify your settings to safely read the environment variables (use get() to handle cases where a variable might be missing):

import os

# Your example KEY variable with a default
KEY = os.environ.get("KEY", "thing")

# Database configuration using environment variables
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",  # or your DB engine
        "NAME": os.environ.get("DB_NAME"),
        "USER": os.environ.get("DB_USER"),
        "PASSWORD": os.environ.get("DB_PASSWORD"),
        "HOST": os.environ.get("DB_HOST"),
    }
}

Pro Tips:

  • Avoid has_key(): This method is deprecated in Python 3. Use var in os.environ or os.environ.get() instead (Django 1.11 supports both Python 2.7 and 3.5+).
  • Logging: Add logging to verify variables are being set correctly (helpful for debugging):
    import logging
    logger = logging.getLogger(__name__)
    
    # Inside the application function, after setting os.environ:
    logger.debug(f"Synced environment variables: {[var for var in REQUIRED_ENV_VARS if var in os.environ]}")
    
  • Mod_wsgi Daemon Mode: If you're using mod_wsgi in daemon mode, ensure your SetEnv directives are in the correct VirtualHost or Location block so the daemon process inherits them.

内容的提问来源于stack exchange,提问作者Steven Franklin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:48:48