簡體   English   中英

根據對象值在基於類的視圖Django中應用Decorator

[英]Apply Decorator in Class Based View Django according to object value

我有一個這樣的模型:

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可調用對象,因此您可以根據需要在運行時應用它們。

您可以采用多種不同的方式來構造它。 在下面,我創建了一個自定義裝飾器,因為這將使您可以在多個CBV中重用相同的代碼。 (當然,這可以進一步推廣。)

請注意,如本文檔所述 ,在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)

如果這令人困惑,則可能會有助於閱讀更多有關裝飾器及其定義和使用方式的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM