【问题标题】:Apply Decorator in Class Based View Django according to object value根据对象值在基于类的视图 Django 中应用装饰器
【发布时间】:2015-03-17 14:54:34
【问题描述】:

我有一个这样的模型:

class Test(models.Model):
    is_private = models.BooleanField(default=False)

我有这样的看法:

class TestDetaiView(View):
    def get(self, request, pk):
         return render(request, 'test.html', {'story': Story.objects.get(pk=pk)}

所以现在,我想做的是:如果测试是私有的,则应用 vary_on_cookie 装饰器,否则使用 cache_page 装饰器。

如何做到这一点?

【问题讨论】:

    标签: python django decorator


    【解决方案1】:

    这里的关键问题是你想在运行时选择装饰器,但通常的装饰器语法是在类声明时触发的。幸运的是,装饰器只是常规的 Python 可调用对象,因此您可以根据需要在运行时应用它们。

    您可以通过多种不同的方式来构建它。下面我创建了一个自定义装饰器,因为它允许您在多个 CBV 中重用相同的代码。 (当然,这可以进一步推广。)

    请注意,正如the documentation 中所讨论的,在 CBV 中应用 Django 装饰器的正确位置是 dispatch() 方法;并且您需要使用 method_decorator 来使 Django 的内置装饰器适合与类一起使用。

    def test_decorator(dispatch_wrapped):
        def dispatch_wrapper(self, request, *args, **kwargs):
            # presumably you're filtering on something in request or the url
            is_private = Test.objects.get(...).is_private
    
            decorator = vary_on_cookie if is_private else cache_page(60 * 15)
            dispatch_decorated = method_decorator(decorator)(dispatch_wrapped)
    
            return dispatch_decorated(self, request, *args, **kwargs)
    
        return dispatch_wrapper
    
    class TestDetaiView(View):
        @test_decorator
        def dispatch(self, *args, **kwargs):
            # any custom dispatch code, or just...
            super().dispatch(*args, **kwargs)
    

    如果这令人困惑,那么阅读更多关于装饰器及其定义和使用方式的信息可能会有所帮助。

    【讨论】:

      【解决方案2】:
      猜你喜欢
      • 2017-03-08
      • 2023-02-07
      • 2020-07-07
      • 1970-01-01
      • 2014-10-20
      • 2012-06-11
      • 2011-08-29
      • 2014-01-21
      • 1970-01-01
      相关资源
      最近更新 更多