Django(27)Django類檢視新增裝飾器

Silent丿丶黑羽 發表於 2021-05-23
Django

類檢視

在寫檢視的時候,Django除了使用函式作為檢視,也可以使用類作為檢視。使用類檢視可以使用類的一些特性,比如繼承等。
 

View

django.views.generic.base.View是主要的類檢視,所有的類檢視都是繼承自他。如果我們寫自己的類檢視,也可以繼承自他。然後再根據當前請求的method,來實現不同的方法。比如這個檢視只能使用get的方式來請求,那麼就可以在這個類中定義get(self,request,*args,**kwargs)方法。以此類推,如果只需要實現post方法,那麼就只需要在類中實現post(self,request,*args,**kwargs)。示例程式碼如下:

from django.views import View
class BookDetailView(View):
    def get(self,request,*args,**kwargs):
        return render(request,'detail.html')

類檢視寫完後,還應該在urls.py中進行對映,對映的時候就需要呼叫View的類方法as_view()來進行轉換。示例程式碼如下:

urlpatterns = [        
    path("detail/<book_id>/",views.BookDetailView.as_view(),name='detail')
]

除了get方法,View還支援以下方法['get','post','put','patch','delete','head','options','trace']
如果使用者訪問了View中沒有定義的方法。比如你的類檢視只支援get方法,而出現了post方法,那麼就會把這個請求轉發給http_method_not_allowed(request,*args,**kwargs)。示例程式碼如下:

class AddBookView(View):
    def post(self,request,*args,**kwargs):
        return HttpResponse("書籍新增成功!")

    def http_method_not_allowed(self, request, *args, **kwargs):
        return HttpResponse("您當前採用的method是:%s,本檢視只支援使用post請求!" % request.method)

urls.py中的對映如下:

path("addbook/",views.AddBookView.as_view(),name='add_book')

如果你在瀏覽器中訪問addbook/,因為瀏覽器訪問採用的是get方法,而addbook只支援post方法,因此以上檢視會返回您當前採用的method是:GET,本檢視只支援使用post請求!。
其實不管是get請求還是post請求,都會走dispatch(request,*args,**kwargs)方法,所以如果實現這個方法,將能夠對所有請求都處理到。
 
Django還為我們提供了很多內建的檢視類,如下

__all__ = [
    'View', 'TemplateView', 'RedirectView', 'ArchiveIndexView',
    'YearArchiveView', 'MonthArchiveView', 'WeekArchiveView', 'DayArchiveView',
    'TodayArchiveView', 'DateDetailView', 'DetailView', 'FormView',
    'CreateView', 'UpdateView', 'DeleteView', 'ListView', 'GenericViewError',
]

小夥伴們如果需要使用,可以去檢視官方文件或者檢視原始碼進行了解
 

給類檢視新增裝飾器

我們訪問首頁如果有登入,則訪問,如果沒有登入則重定向到登入頁,此時可以使用django內建的method_decorator,給類新增裝飾器,示例程式碼如下

from django.utils.decorators import method_decorator
'''自定義登入裝飾器'''
def login_required(func):
    def wrapper(request,*args,**kwargs):
        if request.GET.get("username"):
            return func(request,*args,**kwargs)
        else:
            return redirect(reverse('login'))
    return wrapper

class IndexView(View):
    @method_decorator(login_required)
    def get(self,request,*args,**kwargs):
        return HttpResponse("index")