一尘不染

如何monkey修补Django?

django

我遇到了有关monkey修补Django的帖子:

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。

话虽如此,我只想了解这是如何工作的:

  1. 我将把monkey补丁代码放在哪里?
  2. 代码何时运行-仅运行一次?每个Python解释器启动一次?每个请求一次?
  3. 大概我仍然需要更改数据库架构。因此,如果我放下桌子User运行./manage.py syncdb,会syncdb“知道”是否已添加新字段User吗?如果没有,如何更改架构?

阅读 351

收藏
2020-03-31

共2个答案

一尘不染

你可以将其放置在任何位置,但通常会在设置文件(甚至是urlconf)中看到这种链接。你可以在任何地方发出信号的地方也可能合适。这段代码确实应该稍微聪明一些-通常文件会被多次导入,因此你无能为力,因此,如果你尝试多次运行这样的代码,可能会遇到问题。

对于每个python进程,该代码至少需要执行一次。

是的,你需要手动更改数据库。Syncdb 可能不会捕获更改(我没有仔细研究代码),但是可能在某些地方可以放置代码。

你似乎已经知道这是一件可怕的事情,绝不应该在真正的代码中完成,所以我不会为这一点感到遗憾。除了在将来的Django版本中可能无法使用的代码之外,执行此类操作是一种在代码中生成真正难以发现的错误的绝妙方法。

另外,它不适用于你应该使用的South。

2020-03-31
一尘不染

将文件monkey_patching.py放在你的任何文件中,apps然后将其导入应用程序的__init__.py文件中。即:

app / 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)

app / init.py

#app/__init__.py
import monkey_patching
2020-03-31