0

我有一个由少数 Django 项目/站点共享的大型 Django 应用程序库。在每个项目/站点中,有一个选项可以定义一个“混入”类,该类将被混入库内基类之一(许多模型的子类)。

对于这个例子,假设库内基类是PermalinkBase,混合类是ProjectPermalinkBaseMixIn

因为有这么多模型的子类PermalinkBase,并不是所有定义的方法/属性ProjectPermalinkBaseMixIn都会被所有PermalinkBase的子类使用。

我想编写一个可以应用于其中的方法/属性的装饰器,以便在从未经批准的类访问它们ProjectPermalinkBaseMixIn时限制它们运行(或至少返回)。None

这是我现在的做法:

class ProjectPermalinkBaseMixIn(object):
    """
    Project-specific Mix-In Class to `apps.base.models.PermalinkBase`
    """

    def is_video_in_season(self, season):
        # Ensure this only runs if it is being called from the video model
        if self.__class__.__name__ != 'Video':
            to_return = None
        else:
            videos_in_season = season.videos_in_this_season.all()
            if self in list(videos_in_season):
                to_return = True
            else:
                to_return False

        return to_return

这是我想做的事情:

class ProjectPermalinkBaseMixIn(object):
    """
    Project-specific Mix-In Class to `apps.base.models.PermalinkBase`
    """

    @limit_to_model('Video')
    def is_video_in_season(self, season):
        videos_in_season = season.videos_in_this_season.all()
        if self in list(videos_in_season):
            to_return = True
        else:
            to_return = False

        return to_return

装饰器可以做到这一点吗?这个答案帮助我更好地理解装饰器,但我不知道如何修改它来解决我上面列出的问题。

装饰器是这项工作的正确工具吗?如果是这样,我将如何编写limit_to_model装饰器函数?如果没有,解决这个问题的最佳方法是什么?

4

1 回答 1

1

正在查看您的问题,我认为这可能是实现您想要做的事情的一种过于复杂的方式。但是我写了这段代码:

def disallow_class(*klass_names):
    def function_handler(fn):
        def decorated(self, *args, **kwargs):
            if self.__class__.__name__ in klass_names:
                print "access denied to class: %s" % self.__class__.__name__
                return None
            return fn(self, *args, **kwargs)
        return decorated
    return function_handler


class MainClass(object):

    @disallow_class('DisallowedClass', 'AnotherDisallowedClass')
    def my_method(self, *args, **kwargs):
        print "my_method running!! %s" % self


class DisallowedClass(MainClass): pass

class AnotherDisallowedClass(MainClass): pass

class AllowedClass(MainClass): pass


if __name__ == "__main__":
    x = DisallowedClass()
    y = AnotherDisallowedClass()
    z = AllowedClass()
    x.my_method()
    y.my_method()
    z.my_method()

如果您在命令行上运行这段代码,输出将类似于:

access denied to class: DisallowedClass
access denied to class: AnotherDisallowedClass
my_method running!! <__main__.AllowedClass object at 0x7f2b7105ad50>

问候

于 2012-12-23T18:58:32.870 回答