Django信号通过装饰器的模型方法? [英] Django Signal via Decorator on Model Method?
问题描述
我正在尝试像这些提议的信号装饰器。除了装饰器将装饰的方法与信号(将信号的发送方作为装饰器的参数)连接起来之外,我想在类方法上使用装饰器。
I'm trying to do something like these proposed signal decorators. In addition to having a decorator that connects the decorated method to a signal (with the signal's sender as an argument to the decorator), I would like to use the decorator on class methods.
我想使用这样的装饰器:
I'd like to use the decorator like so:
class ModelA(Model):
@connect.post_save(ModelB)
@classmethod
def observe_model_b_saved(cls, sender, instance, created, **kwargs):
# do some stuff
pass
装饰器是:
from django.db.models import signals
def post_save(sender):
def decorator(view):
signals.post_save.connect(sender=sender, receiver=view)
return view
return decorator
当我这样做时,我得到错误是:
The error I get when I do this is:
File "/Library/Python/2.6/site-packages//lib/python2.6/site-packages/django/dispatch/dispatcher.py", line 78, in connect
AssertionError: Signal receivers must be callable.
我猜问题是 @classmethod
返回一个类方法对象不可调用我真的不明白 classmethod
是如何工作的,但是我从此参考页面,类方法对象在从类中访问之前不会转换为可调用对象,例如, ModelA.observe_model_b_saved
。有没有什么方法我可以同时(1)将我的方法定义为模型的类或实例方法,(2)使用装饰器直接在方法定义上将其连接到信号?谢谢!
I guess the problem is that @classmethod
returns a class method object which is not callable. I don't really understand how classmethod
works under the hood, but I surmise from this reference page that the class method object is not translated into a callable until it is accessed from the class, e.g., ModelA.observe_model_b_saved
. Is there any way that I can both (1) define my method as a class or instance method on a model, and (2) connect it to a signal using a decorator directly on the method definition? Thanks!
推荐答案
您的示例代码不清楚,所以我会问,信号侦听器是否实际上必须是 @classmethod
?即如果您还需要访问该类,那么常规方法会执行(然后使用 self .__ class __
)?它是否需要一个方法(可以使用一个函数)?
It's not clear from your example code, so I'd be asking if the signal listener actually has to be a @classmethod
? I.e. Will a regular method do (and then use self.__class__
if you still need to access the class itself)? Does it need to be a method at all (can you just use a function)?
另一种选择可能是使用第二种方法来收听信号并委托调用 @classmethod
:
Another option might be to use a second method to listen to the signal and delegate the call to the @classmethod
:
class ModelA(Model):
@classmethod
def do_observe_model_b_saved(cls, sender, instance, created, **kwargs):
# do some stuff
pass
@connect.post_save(ModelB)
def observe_model_b_saved(self, sender, instance, created, **kwargs):
self.do_observe_model_b_saved(sender, instance, created, **kwargs)
这篇关于Django信号通过装饰器的模型方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!