假设我有以下模型 -
class Banana(models.Model):
name = models.CharField(max_length=255)
def get_banana(self):
return f'Banana: {self.name}'
现在,我想添加一个记录器,每当该方法成功启动和结束时,都会生成一个日志get_banana
。
记录器如下 -
class Log(models.Model):
type = models.CharField(max_length=255)
message = models.CharField(max_length=255)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
所以我创建了一个记录器装饰器-
def log_status(f):
def wrapper(**fields):
Log.objects.create(**{k: (v if k != 'message' else v + ':STARTED') for k, v in fields.items()})
return_value = f()
Log.objects.create(**{k: (v if k != 'message' else v + ':COMPLETED') for k, v in fields.items()})
return return_value
return wrapper
如何将此装饰器添加到我的get_banana
方法中?
以下内容不起作用,因为它看不到self
。
@log_status(type='info', message='Get Banana.', content_object=self)
def get_banana(self):
return f'Banana: {self.state}'
由于您正在装饰方法,因此装饰器实际上可以使用self
。它在解析时不可用,但肯定会在运行时可用。您需要做的就是像这样更改装饰器:
def log_status(function):
def wrapper(self, *args, **kwargs):
return_value = function(self, *args, **kwargs) # do whatever you want here
return return_value
return wrapper
就这样。现在在运行时,self 将可供装饰器使用,并将传递给它,您的函数应按预期执行。