0

少数のDjangoプロジェクト/サイトで共有されているDjangoアプリの大規模なライブラリがあります。各プロジェクト/サイト内には、ライブラリ内の基本クラス(多くのモデルがサブクラスになっている)の1つにミックスインされる「ミックスイン」クラスを定義するオプションがあります。

この例では、ライブラリ内の基本クラスが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 に答える