【问题标题】:Can I create a custom decorator for a model method in Django?我可以在 Django 中为模型方法创建自定义装饰器吗?
【发布时间】:2018-08-15 03:13:10
【问题描述】:

假设我有以下模型 -

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}'

【问题讨论】:

    标签: python django model decorator


    【解决方案1】:

    由于你正在装饰一个方法,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 并将其传递给它,您的函数应该按预期执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-10
      • 2011-08-10
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多