1

I have a Django Model (MyModel) with a decorated method (my_method). I expect the decorators to perform some checks on my_method:

  • if the checks succeed, my_method should return a string;

  • if the checks do not succeed, my_method should return the failure messages returned by the decorators.

The logic is the following:

# models.py
class MyModel(models.Model):
    @decorator1
    @decorator2
    def my_method(self, request, *args, **kwargs):
        return u'The result that must be returned if all the checks performed by the decorator succeed'


# decorators.py
from functools import wraps

# decorator1 checks if certain conditions are met. If yes, it returns the decorated method (method_to_decorate); if not, it returns a tuple
def decorator1(method_to_decorate):
    @wraps(method_to_decorate)
    def wrapper1(self, request, *args, **kwargs):
        if a_condition :
            return method_to_decorate(self, request, *args, **kwargs)
        else:
            # we return a failure message
            return ('failure', 'message') 
    return wrapper1

# in decorator2, we want to know if the check performed by decorator1 was successful
# in case of success, we perform decorator2's check
# in case of failure, decorator2 should simply pass the failure message returned by decorator1   
def decorator2(method_to_decorate):
    @wraps(method_to_decorate)
    def wrapper2(self, request, *args, **kwargs):

        # if the first decorator succeeded
        if decorator1_s_test_was_successful:
            # we check if the conditions of the second decorator are met
            if decorator2_s_test_was_successful:
                # we return the method
                return method_to_decorate(self, request, *args, **kwargs)
            else:
                # we return a failure message
                return ('another failure', 'message')
    # if the first decorator did not succeed
        else: # decorator1 returned a tuple : ('failure', 'message') 
            return the_failure_that_decorator1_returned  
    return wrapper2

したがって、decorator1 が失敗を返した場合、an_instance_of_my_model_instance.my_method(request) が ('failure', 'message') を返すことを期待しています。decorator1 が成功したが、decorator2 が成功しなかった場合、('another failure', 'message') を期待します。そして、すべてのテストに合格した場合、「デコレータによって実行されたすべてのチェックが成功した場合に返される必要がある結果」

decorator1 のチェックが成功した場合、decorator2 をチェックインする方法がわかりません。decorator2のmethod_to_decorateのtype()を調べてみたのですが、typeはdecorator1が返す結果ではなく、元のメソッドそのものを使っているようです(あたかもデコレータが以前のデコレータが行った操作を知らなかったかのように)。 .

前もって感謝します!

4

2 に答える 2

4

デコレータは、装飾されたメソッドの上に配置した順序で呼び出され、プログラム構造が与えられた場合、失敗したdecorator2場合は呼び出されないため、で成功したdecorator1かどうかを確認する必要はありません。decorator1decorator2

もう少し簡単な例...

from functools import wraps


def decorator1(f):
    @wraps(f)
    def wrapper(a):
        if a >= 1:
            return f(a)
        return 'failed in decorator 1'
    return wrapper

def decorator2(f):
    @wraps(f)
    def wrapper(a):
        if a >= 2:
            return f(a)
        return 'failed in decorator 2'
    return wrapper

@decorator1
@decorator2
def my_func(a):
    return 'success'


print my_func(0)
print my_func(1)
print my_func(2)

...印刷...

failed in decorator 1
failed in decorator 2
success
于 2013-06-19T12:55:22.830 に答える