Django如何补丁? [英] How to monkey patch Django?

查看:138
本文介绍了Django如何补丁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在猴子修补Django时发现了这个帖子:来自django.contrib.auth.models的用户

User.add_to_class('openid')

 models.CharField(max_length = 250,blank = True))

def get_user_name(self):
如果self.first_name或self.last_name:
return self.first_name + + self.last_name
return self.username

User.add_to_class(get_user_name,get_user_name)

我知道这不是理想的,最好通过单独的模型添加字段和函数到 User 个人资料



正如我所说,我只是想了解这将如何工作:


  1. 我将在哪里放置猴子补丁代码?


  2. 代码运行何时运行 - 只是一次?每次Python解释器启动一次?每次请求一次?


  3. 我可能还需要更改数据库模式。所以如果我删除了表用户并运行 ./ manage.py syncdb ,将 syncdb 知道新字段已添加到用户?如果不是如何更改模式?



解决方案

你可以把它在任何地方,但是在设置文件(甚至是urlconf)中看到这样的东西是很常见的。任何地方你可以放一个信号也可能是适当的。这个代码实际上应该稍微更智能 - 通常文件不止一次导入,你可以做很多事情,所以如果您尝试多次运行这样的代码,可以遇到问题。



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



是的,您需要手动更改数据库。 Syncdb 可能不会捕捉到这个变化(我没有仔细看看代码),但是可能会有一些地方可以使代码可以工作。



你似乎已经知道这是一个可怕的,可怕的事情,不应该为真正的代码做,所以我不会反对这一点。除了在未来版本的Django中可能无法使用的代码之外,做这样的事情是一种非常难以发现错误的奇妙方法。



另外对于您应该使用的南方来说,它不会奏效。


I came upon this post on monkey patching 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)

I understand that this isn't ideal and it's better to add fields and functions to User through a separate model Profile.

With that said, I just want to understand how this would work:

  1. Where would I put the monkey patching code?

  2. When is the code run -- just once? once per Python interpreter startup? once per request?

  3. Presumably I'd still need to change the DB schema. So if I dropped the table User and ran ./manage.py syncdb, would syncdb "know" that a new field has been added to User? If not how do I change the schema?

解决方案

You could put it anywhere, but it's common to see this kind of stuff linked in the settings file (or even the urlconf). Anywhere you could put a signal might also be appropriate. This code should really be slightly more intelligent - often files get imported more than once and there's not a lot you can do about it, so you can run into problems if you try to run code like this multiple times.

The code needs to be executed at least once for each python process.

Yes you would need to change the DB by hand. Syncdb probably wouldn't catch the change (I haven't looked closely at the code), but there might be some places you could put the code that would work.

You seem to already know that this is a terrible, horrible thing to do and should never be done for real code, so I won't belabor that point. Doing this kind of thing is a fantastic way to generate really difficult to find bugs in your code, in addition to code that may not work in future versions of Django.

Also, it won't work well with South, which you should be using.

这篇关于Django如何补丁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆