我在猴子修补Django时遇到了这个post:
from django.contrib.auth.models import User
User.add_to_class('openid', models.CharField(max_length=250,blank=True))
def get_user_name(self):
if self.first_name or self.last_name:
return self.first_name + " " + self.last_name
return self.username
User.add_to_class("get_user_name",get_user_name)
我知道这并不理想,最好通过单独的模型User
向Profile
添加字段和函数。
话虽如此,我只是想了解这是如何工作的:
我会把猴子修补代码放在哪里?
代码何时运行 - 只需一次?每个Python解释器启动一次?每次请求一次?
据推测,我仍然需要更改数据库架构。因此,如果我删除了表User
并运行./manage.py syncdb
,那么syncdb
会“知道”已将新字段添加到User
吗?如果不是,我该如何更改架构?
答案 0 :(得分:14)
将文件monkey_patching.py
放入您的apps
中,然后将其导入应用的__init__.py
文件中。即:
应用/ monkey_patching.py 强>
#app/monkey_patching.py
from django.contrib.auth.models import User
User.add_to_class('openid', models.CharField(max_length=250,blank=True))
def get_user_name(self):
if self.first_name or self.last_name:
return self.first_name + " " + self.last_name
return self.username
User.add_to_class("get_user_name",get_user_name)
应用/ __初始化__。PY 强>
#app/__init__.py
import monkey_patching
答案 1 :(得分:6)
你可以把它放在任何地方,但是在设置文件(甚至是urlconf)中链接这种东西是很常见的。您可以放置信号的任何地方也可能是合适的。这段代码应该更加智能 - 通常文件会被多次导入,而且你可以做很多事情,所以如果你多次尝试运行这样的代码,你可能会遇到问题。
每个python进程需要至少执行一次代码。
是的,您需要手动更改数据库。 Syncdb 可能无法捕获更改(我没有仔细查看代码),但可能有一些地方可以放置可行的代码。
你似乎已经知道这是一个可怕的,可怕的事情,永远不应该为真正的代码完成,所以我不会那么说。除了在未来版本的Django中可能无法运行的代码之外,做这种事情是在代码中生成真正难以发现的错误的绝妙方法。
此外,它不适用于你应该使用的南方。