Re: [python] [django] [mod_pyth on] [apache] 再次质疑Django+Mod_python 时对环境变量的处理

"vcc" <vcc-9Onoh4P/[email protected]>
Newsgroups gmane.comp.python.chinese
Message-ID <B101C9758F4E43B8B34C95FD0EAD54F2@wgjPC>
> 发现Django开发组已经注意到,mod_python不理会apache的setENV指令:
>
>        # mod_python fakes the environ, and thus doesn't process
> SetEnv.  This fixes that
>        os.environ.update(req.subprocess_env)
>
> 但是这个和SetEnv DJANGO_SETTINGS_MODULE app.settings
> 自相矛盾矛盾,真晕,自己不设置正确的,也不搭理管理员指定的,怎么办?

这个并不自相矛盾,SetEnv不是mod_python处理的,而是mod_env处理的,处理的结果就在req.subprocess_env,只是mod_python并没有赋值给os.environ,所以Django要自己搞一下。问题就在于os.environ.update的时候还putenv了,一般来讲修改过环境变量要恢复回去,Django没有干这个事。给一个小补丁来干这个:

Index: modpython.py
===================================================================
--- modpython.py (revision 7003)
+++ modpython.py (working copy)
@@ -141,6 +141,8 @@

     def __call__(self, req):
         # mod_python fakes the environ, and thus doesn't process SetEnv. 
This fixes that
+        # First save env, after finished restore
+        save_env = os.environ.copy()
         os.environ.update(req.subprocess_env)

         # now that the environ works we can see the correct settings, so 
imports
@@ -166,6 +168,12 @@
                 response = self.apply_response_fixes(request, response)
         finally:
             dispatcher.send(signal=signals.request_finished)
+            osenv = os.environ
+            # restore env
+            for k in osenv.keys():
+                del osenv[k]
+            for k in sav_env:
+                osenv[k] = sav_env[k]

         # Convert our custom HttpResponse object back into the mod_python 
req.
         req.content_type = response['Content-Type']

这样就可以把
import os, pwd
os.environ["HOME"] = pwd.getpwuid(os.getuid()).pw_dir

加到这里面,不违反DRY原则吧 ;-)


> 后来在http://code.google.com/p/modwsgi/wiki/ApplicationIssues找到一些类似的情况,
> 提到sudo的时候有bug,会导致HOME和root启动的HOME不一样,太好了,我就要这样的bug。
> 设置hackgou账号的sudo权限,然后用sudo来启动apache,果然所有的expanduser('~/')都顺利。
> 除此之外, 文中提到
>
> import os, pwd
> os.environ["HOME"] = pwd.getpwuid(os.getuid()).pw_dir
>
> 这样的代码,似乎可以解决这个问题,神啊,我很反感这种做法:
> 1.django中似乎没有地方可以放置这样的需要这个APP都需要的代码,我的DRY啊
> 2.Django修改环境变量似乎成了习惯,之前碰到个TIME_ZONE的问题,就是因为修改了APACHE的环境变量,导致
> 别的应用环境受到污染,要知道一个apache进程是很多应用共享的,
> 除了Djano还有别的应用,比如别的Django应用或者PHP,都有可能在一个相同的APACHE进程空间中处理,
> 说有可能是因为apache本身的一些设置会出现这些差别,跟py没有关系,
> 这样会导致他们的工作环境受到污染。这似乎没有好的方法可以解决这个问题,
> 对Django或者说对mod_python 的这种拖泥带水的做法感觉非常的不爽。
> 也不知道有没有更好的更彻底的解决方法?
> 如果谁知道,能够告诉我那是最好不过的了
>



_______________________________________________
python-chinese
Post: send [email protected]
Subscribe: send subscribe to [email protected]
Unsubscribe: send unsubscribe to  [email protected]
Detail Info: http://python.cn/mailman/listinfo/python-chinese
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.