Archive for the 'django' Category

再次质疑Django+M od_python时对环境 变量的处理

今天在升级一个django开发的系统到V2的时候,
发现~/无法正确的展开成 /home/hackgou.(apache是以hackgou帐号执行的,)
也不会展开成/root(apache是以root启动的) 觉得非常奇怪,
就算是用os.path.expanduser(’~/’)也无济于事。 于是怀疑是os.envrion[’HOME’]不对,
因为expanduser是需要这个变量来展开~/的。 于是使用setenv HOME /home/hackgou/ 可是也不工作,
后来在django/core/handlers/modpython.py的ModPythonHandler中 发现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 自相矛盾矛盾,真晕,
自己不设置正确的,也不搭理管理员指定的,怎么办?
后来在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 的这种拖泥带水的做法感觉非常的不爽。
也不知道有没有更好的更彻底的解决方法?
如果谁知道,能够告诉我那是最好不过的了

让easy_install构造自己的py thon小天地

在linux环境中玩、用python,常常需要安装额外的一些python lib
但是由于权限的问题,我们一般是无法往系统中/usr/local之类的目录
里面写东西的,而这些额外的lib又非得需要一个site-packages目录来安装
不可,虽然可以指定pure-lib之类的参数,但是很多时候还是会出错,尤其是现在很多python
lib都是使用的setuptools来生成安装包,更是如此要求了,

  1. [gavin@Korea downloads]$ ll /usr/local/python24/lib/python2.4/site-packages/
  2. total 24
  3. drwxr-xr-x  2 root root 4096 Dec 18 16:05 PIL
  4. -rw-r--r--  1 root root    4 Dec 18 16:05 PIL.pth
  5. -rw-r--r--  1 root root  119 Dec 18 14:59 README

这可麻烦了,每个文件都是root的,旁人只能看,
其实这儿有个很好的解决方法:在自己的目录下面,安装一个虚拟的python:
在自己的目录下面建立一些lib、include等等的目录,构成一个独立的python小天地,这样,系统范围内没有的python库,就可以自己动手安装在自己的小天地中
安装,既不需要root权限,又可以满足自己的需求,一举两得。
这些安装步骤,当然不需要我们重新造轮子,下载
http://peak.telecommunity.com/dist/virtual-python.py
这个脚本,使用你喜欢的python(有的环境提供多个python版本,比如DreamHost)
执行一下这个virtual-python.py,就会自动在~/下面建立所需的目录(~/bin、/lib、
~/include),以及所需python版本,以及创建python所依赖的其他的.h头文件、.py库文件等等软链接,而且会在~/bin/下面copy一个可以执行的python文件,以后直接使用这个~/bin/python来执行py程序,它就会自动找到额外安装在小天地中的那些python库了。如果觉得把bin、lib、include放在~下面不好可以给virtual-python.py指定一个–prefix参数:

  1. [gavin@Korea bin]$ python24 virtual-python.py --prefix=~/python-lib
  2. [gavin@Korea bin]$ pwd
  3. /home/gavin/python-lib/bin
  4. [gavin@Korea bin]$ ll
  5. total 2360
  6. -rwxrwxr-x  1 gavin gavin 2404367 Dec 18 16:53 python

会把那些bin、lib、include安装在~/python-lib下面,
这下,你就可以使用easy__install来安装自己额外需要的那些库了,
不过等等先,由于此时使用的easy_install是系统范围的,所以它会把东西安装在
/usr/local之类的目录下,所以我们得给我们自己的环境安装一个easy_install。
下载

  1. wget http://peak.telecommunity.com/dist/ez_setup.py
  2. ~/python-lib/bin/python ez_setup.py
  3. Downloading http://cheeseshop.python.org/packages/2.4/s/setuptools/setuptools-0.6c3-py2.4.egg
  4. Processing setuptools-0.6c3-py2.4.egg
  5. creating /home/gavin/python-lib/lib/python2.4/site-packages/setuptools-0.6c3-py2.4.egg
  6. Extracting setuptools-0.6c3-py2.4.egg to
  7. /home/gavin/python-lib/lib/python2.4/site-packages
  8. Adding setuptools 0.6c3 to easy-install.pth file
  9. Installing easy_install script to /home/gavin/python-lib/bin
  10. Installing easy_install-2.4 script to /home/gavin/python-lib/bin
  11.  
  12. Installed /home/gavin/python-lib/lib/python2.4/site-packages/setuptools-0.6c3-py2.4.egg
  13. Processing dependencies for setuptools==0.6c3
  14. [gavin@Korea downloads]$ ll ~/python-lib/bin/
  15. total 2376
  16. -rwxr-xr-x  1 gavin gavin     298 Dec 18 17:02 easy_install
  17. -rwxr-xr-x  1 gavin gavin     306 Dec 18 17:02 easy_install-2.4
  18. -rwxrwxr-x  1 gavin gavin 2404367 Dec 18 16:53 python

好了,我自己的easy_install已经安装好了,就可以使用它来安装
自己想安装的所有东西了,而且不用担心权限的问题:

  1. [gavin@Korea downloads]$ ll ~/python-lib/lib/python2.4/site-packages/

我好像没有simplejson呢,ok,安装一个,先:

  1. [gavin@Korea downloads]$ ~/python-lib/bin/easy_install simplejson
  2. Searching for simplejson
  3. Reading http://www.python.org/pypi/simplejson/
  4. Reading http://undefined.org/python/#simplejson
  5. Reading http://www.python.org/pypi/simplejson/1.4
  6. Best match: simplejson 1.4
  7. Downloading http://cheeseshop.python.org/packages/2.4/s/simplejson/simplejson-1.4-py2.4.egg#md5=4f18e31fd095cd54e5015e7b7a147093
  8. Processing simplejson-1.4-py2.4.egg
  9. Moving simplejson-1.4-py2.4.egg to
  10. /home/gavin/python-lib/lib/python2.4/site-packages
  11. Adding simplejson 1.4 to easy-install.pth file
  12.  
  13. Installed /home/gavin/python-lib/lib/python2.4/site-packages/simplejson-1.4-py2.4.egg
  14. Processing dependencies for simplejson
  15. [gavin@Korea downloads]$ ll ~/python-lib/lib/python2.4/site-packages/
  16. total 76
  17. -rw-rw-r--  1 gavin gavin   241 Dec 18 17:07 easy-install.pth
  18. lrwxrwxrwx  1 gavin gavin    51 Dec 18 16:53 PIL ->
  19. /usr/local/python24/lib/python2.4/site-packages/PIL
  20. lrwxrwxrwx  1 gavin gavin    55 Dec 18 16:53 PIL.pth ->
  21. /usr/local/python24/lib/python2.4/site-packages/PIL.pth
  22. lrwxrwxrwx  1 gavin gavin    54 Dec 18 16:53 README ->
  23. /usr/local/python24/lib/python2.4/site-packages/README
  24. drwxrwxr-x  4 gavin gavin  4096 Dec 18 17:02 setuptools-0.6c3-py2.4.egg
  25. -rw-rw-r--  1 gavin gavin    29 Dec 18 17:02 setuptools.pth
  26. -rw-rw-r--  1 gavin gavin 35898 Dec 18 17:07 simplejson-1.4-py2.4.egg
  27. [gavin@Korea downloads]$

非常漂亮

  1. [gavin@Korea downloads]$ ~/python-lib/bin/python
  2. Python 2.4.4 (#1, Dec 18 2006, 14:54:46)
  3. [GCC 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)] on linux2
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. >>> import simplejson
  6. >>> dir(simplejson)
  7. ['JSONDecoder', 'JSONEncoder', '__all__', '__builtins__', '__doc__',
  8. '__file__', '__loader__', '__name__', '__path__', '__version__',
  9. 'decoder', 'dump', 'dumps', 'encoder', 'load', 'loads', 'read',
  10. 'scanner', 'write']
  11. >>>

这个法子对使用dreamhost这类的虚拟主机带来的便利是非常好的,所有的都是自己独立的,再也不用担心Django找不到PIL、找不到……出错了,也不需要在fcgi转发程序里面添加一堆的sys.path,美哉!

shell下调试Django的方便小toolkit

在调试的时候,有时候shell下面是很方便的。 除了manage.py shell之外,下面这几行代码可以帮我们不少忙。

  1. #shell.py
  2. import os 
  3. import sys 
  4. os.environ['DJANGO_SETTINGS_MODULE'] = "app.settings" 
  5. sys.path.append(os.getcwd())    #shell.py 和其他module的路径有可能要修改
  6. from app.mymod.models import mymod

这样 就可以调试mymod了!比较方便! :D 其实说白了就是那个’DJANGO_SETTINGS_MODULE’环境变量没有设置,设置了之后就好了! 后面的from app.mymod.models import mymod是为了方便,免得每次调试都输入这些import。

使用函数调用来默认值填充models中字段的默认值

使用函数调用来默认值填充models中字段的默认值,比如使用 datetime.datetime.now来填充 字段类型为日期型的时候最为有用,当然不只可以用于日期型字段。扩展一下,完 全可以使 用自定义的方法来填充默认值

Model source code
from django.db import models from datetime import datetime
class Article(models.Model): headline = models.CharField(maxlength=100, default=’Default headline’) pub_date = models.DateTimeField(default=datetime.now)
def __str__(self): return self.headline

Django中这样翻页,一个字,简单

29. Object pagination
Django provides a framework for paginating a list of objects in a few lines of code. This is often useful for dividing search results or long lists of objects into easily readable pages.
Model source code
from django.db import models
class Article(models.Model): headline = models.CharField(maxlength=100, default=’Default headline’) pub_date = models.DateTimeField()
def __str__(self): return self.headline
Sample API usage
This sample code assumes the above model has been saved in a file mysite/models.py.
>>> from mysite.models import Article
# prepare a list of objects for pagination >>> from datetime import datetime >>> for x in range(1, 10): …. a = Article(headline=’Article %s’ % x, pub_date=datetime(2005, 7, 29)) …. a.save()
# create a basic paginator, 5 articles per page >>> from django.core.paginator import ObjectPaginator, InvalidPage >>> paginator = ObjectPaginator(Article.objects.all(), 5)
# the paginator knows how many hits and pages it contains >>> paginator.hits 9
>>> paginator.pages 2
# get the first page (zero-based) >>> paginator.get_page(0) [, , , , ]
# get the second page >>> paginator.get_page(1) [, , , ]
# does the first page have a next or previous page? >>> paginator.has_next_page(0) True
>>> paginator.has_previous_page(0) False
# check the second page >>> paginator.has_next_page(1) False
>>> paginator.has_previous_page(1) True
>>> paginator.first_on_page(0) 1 >>> paginator.first_on_page(1) 6 >>> paginator.last_on_page(0) 5 >>> paginator.last_on_page(1) 9

Creative Commons License
This work is licensed under a Creative Commons License.