Django信号通过装饰器的模型方法? [英] Django Signal via Decorator on Model Method?

查看:125
本文介绍了Django信号通过装饰器的模型方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试像这些提议的信号装饰器。除了装饰器将装饰的方法与信号(将信号的发送方作为装饰器的参数)连接起来之外,我想在类方法上使用装饰器。

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屋!

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