Why do I need to decorate login_required decorator with @method_decorator

后端 未结 1 1551
误落风尘
误落风尘 2021-02-04 12:37

I am trying to understand the code for the mixins posted at this blog post.

These mixins call the login_required decorator from django.contrib.auth.de

相关标签:
1条回答
  • 2021-02-04 12:59

    Django's method_decorator is set up to pass the self argument in correctly to the decorated function. The reason this doesn't show up in the test cases you wrote above with the run_eight_times decorator is that the inner_func in run_eight_times blindly passes all arguments in to myfunc via *args and **kwargs. In general, this won't be the case.

    To see this with your example, try the following:

    from django.utils.decorators import method_decorator
    
    def run_eight_times(myfunc):
        def inner_func(what_he_likes, **kwargs):
            # override...
            what_he_likes = 'pizza'
            for i in range(8):
                myfunc(what_he_likes, **kwargs)
        return inner_func
    
    class MyClass(object):
    
        def __init__(self, name, favorite_dish):
            self.name = name
            self.favorite_dish = favorite_dish
    
        # This next line required!
        @method_decorator(run_eight_times)
        #@run_eight_times
        def undecorated_function(self, what_he_likes):
            print "%s likes %s in his favorite dish %s" % (
                self.name, what_he_likes, self.favorite_dish
            )
    
    def main():
        inst = MyClass('bob', 'burrito')
        inst.undecorated_function('hammy spam')
    
    if __name__ == '__main__':
        main()
    

    Specifically, Django's view decorators will return a function with a signature (request, *args, **kwargs). For a class based-view, this should be (self, request, *args, **kwargs). That's what method_decorator does - transform the first signature into the second.

    0 讨论(0)
提交回复
热议问题