How to add new method to Django class from other modules?
我有一个Django模特说:
1 2 3 4 5
| class MyOperation(models.Model):
name = models.CharField(max_length=100)
def my_method(self):
pass |
我想从另一个Django应用程序向这个类添加一个新方法。
我尝试从另一个名为custom.py的应用程序模块执行此操作:
1 2 3 4 5 6
| from operations.models import MyOperation
def op_custom(test):
print"testing custom methods"
MyOperation.op_custom = op_custom |
但是,这似乎不起作用,在运行时,该方法不存在。
这是从不同的django应用程序修改类定义的方法吗?有更好的方法吗?
谢谢
- 1。不要这样做。2。不要这样做。三.这打破了对Python代码的内省和人为解析,因此不应该这样做。4。不要。5。如果您必须这样做,您可以,如@knbk's link所示。
- 这不是同一个问题,我在问如何在django模型中添加方法,我的意思是,类,而不是对象。
- @约瑟路易斯德拉罗莎,这正是链接的答案,除非我误解了你的实际要求。一个问题-您是否在custom.py中运行代码?
- @Astex什么样的内省没有找到新的方法?inspect模块似乎工作正常。但我认为,这有时是不可避免的Django模型。如果没有副作用,就不能简单地将第三方模型划分为子类。
- 埃多克斯1〔1〕接他们,但他们不是来自埃多克斯1〔3〕的任何地方。一些Python库(例如flask classy或my own[private]project foodtoeat.com)使用一个复杂的系统,该系统涉及到遍历mro()并获取方法的参数规范,以正确地路由到类中的方法。在这些情况下,猴子修补的方法将被完全忽略。
- 虽然您不能在django应用程序中对第三方模型进行子类化(由于使用了元类),但您可以添加另一层元类和代理类,以更合理的方式进行此操作。我不确定它是否真的会简化实现,或者它是否只是帮助组织代码。最好只使用将对象作为参数的函数。
- 值得注意的是,除了@knbk链接的步骤之外,还应该使用wrapps decorator来维护元数据:MyOperation.my_method = wraps(MyOperation.my_method)(op_custom)。
正确的方法?要做到这一点,需要通过混音器:
1 2 3 4 5 6 7
| class MyMixIn(object):
def op_custom(self):
print("foo")
class MyOperation(models.Model, MyMixIn):
def op_normal(self):
print("bar") |
与另一种方法中的猴子修补相比,这有几个优点:
- mixin是类的方法解析顺序,因此内省工作得很好。
- 它保证在类的每个实例上定义,不管它在何处实例化,因为类本身继承自mixin。否则,在应用monkey补丁之前,如果没有此方法,您可能会得到一些实例。
- 它为将来添加此类方法提供了一个明显的位置。
- 模型的继承不应该被颠倒,例如mymixin应该在建模之前出现。class MyOperation(MyMixIn, models.Model)
- @它取决于预期用途。如果mixin应重写Model类中的方法,则为yes。但是,有些情况需要相反的结果。例如,可以使用mixin通过编写自定义save()来"欺骗"模型类,…方法,同时提供可通过继承方法与实际模型一起使用的附加功能。
- 这既不能回答问题,也不能达到同样的目的。将mixin添加到原始实例的__bases__中可能会改进答案。