Django drf 基于類(lèi)的視圖

2020-01-22 11:45 更新

基于類(lèi)的視圖

Django中基于類(lèi)的視圖對(duì)于舊式風(fēng)格的視圖來(lái)說(shuō)是良好的替代品?!?nbsp;reinout van rees

REST framework提供了一個(gè)APIView類(lèi),它是Django的View類(lèi)的子類(lèi)。

APIView類(lèi)和一般的View類(lèi)有以下不同:

  • 被傳入到處理方法的請(qǐng)求不會(huì)是Django的HttpRequest類(lèi)的實(shí)例,而是REST framework的Request類(lèi)的實(shí)例。
  • 處理方法可以返回REST framework的Response,而不是Django的HttpRequest。視圖會(huì)管理內(nèi)容協(xié)議,給響應(yīng)設(shè)置正確的渲染器。
  • 任何APIException異常都會(huì)被捕獲,并且傳遞給合適的響應(yīng)。
  • 進(jìn)入的請(qǐng)求將會(huì)經(jīng)過(guò)認(rèn)證,合適的權(quán)限和(或)節(jié)流檢查會(huì)在請(qǐng)求被派發(fā)到處理方法之前運(yùn)行。

使用APIView類(lèi)和使用一般的View類(lèi)非常相似,通常,進(jìn)入的請(qǐng)求會(huì)被分發(fā)到合適處理方法比如.get(),或者.post。另外,很多屬性會(huì)被設(shè)定在控制API策略的各種切面的類(lèi)上。

比如:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions

class ListUsers(APIView):
    """
    列出系統(tǒng)中的所有用戶(hù)的視圖。

    * 需要token認(rèn)證
    * 只有管理員用戶(hù)可以訪問(wèn)這個(gè)視圖。
    """
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (permissions.IsAdminUser,)

    def get(self, request, format=None):
        """
        Return a list of all users.
        """
        usernames = [user.username for user in User.objects.all()]
        return Response(usernames)

API策略屬性

下面這些屬性控制了API視圖可拔插的那些方面。

.renderer_classes
.parser_classes
.authentication_classes
.throttle_classes
.permission_classes
.content_negotiation_class

API policy instantiation methods

下面這些方法被REST framework用來(lái)實(shí)例化各種可拔插的API策略。你通常不需要重寫(xiě)這些方法。

.get_renderers(self)
.get_parsers(self)
.get_authenticators(self)
.get_throttles(self)
.get_permissions(self)
.get_content_negotiator(self)
.get_exception_handler(self)

API policy implementation methods

下面這些方法會(huì)在請(qǐng)求被分發(fā)到具體的處理方法之前調(diào)用。

.check_permissions(self, request)
.check_throttles(self, request)
.perform_content_negotiation(self, request, force=False)

Dispatch methods

下面這些方法會(huì)被視圖的.dispatch()方法直接調(diào)用。它們?cè)谡{(diào)用.get, .post(), put(), patch()和delete()之類(lèi)的請(qǐng)求處理方法之前或者之后執(zhí)行任何需要執(zhí)行的操作。

.initial(self, request, *args, **kwargs)

在處理方法調(diào)用之前進(jìn)行任何需要的動(dòng)作。 這個(gè)方法用于執(zhí)行權(quán)限認(rèn)證和限制,并且執(zhí)行內(nèi)容協(xié)商。 你通常不需要重寫(xiě)此方法。

.handle_exception(self, exc)

任何被處理請(qǐng)求的方法拋出的異常都會(huì)被傳遞給這個(gè)方法,這個(gè)方法既不返回Response的實(shí)例,也不重新拋出異常。

默認(rèn)的實(shí)現(xiàn)會(huì)處理rest_framework.expceptions.APIException的任何子類(lèi)異常,以及Django的Http404和PermissionDenied異常,并且返回一個(gè)適當(dāng)?shù)腻e(cuò)誤響應(yīng)。

如果你需要在自己的API中自定義返回的錯(cuò)誤響應(yīng),你需要重寫(xiě)這個(gè)方法。

.initialize_request(self, request, *args, **kwargs)

確保傳遞給請(qǐng)求處理方法的請(qǐng)求對(duì)象是Request的實(shí)例,而不是通常的DjangoHttpResquest的實(shí)例。

你通常不需要重寫(xiě)這個(gè)方法。

.finalize_response(self, request, response, *args, **kwargs)

確保任何從處理請(qǐng)求的方法返回的Response對(duì)象被渲染到由內(nèi)容協(xié)商決定的正確內(nèi)容類(lèi)型。

你通常不需要重寫(xiě)這個(gè)方法。

基于函數(shù)的視圖

說(shuō)[基于類(lèi)的視圖]不管什么時(shí)候都是更好的解決方案,那是錯(cuò)誤的?!?nbsp;Nick Coghlan

在REST framework中,你也可以使用常規(guī)的基于函數(shù)的視圖。它提供了一組簡(jiǎn)單的裝飾器,用來(lái)包裝你的視圖函數(shù),以確保視圖函數(shù)會(huì)收到Request(而不是Django一般的HttpRequest)對(duì)象,并且返回Response(而不是Django的HttpResponse)對(duì)象,同時(shí)允許你設(shè)置這個(gè)請(qǐng)求的處理方式。

@api_view()

函數(shù)簽名: @api_view(http_method_names=['GET'], exclude_from_schema=False)

此功能的核心是api_view裝飾器,它接受視圖應(yīng)該響應(yīng)的HTTP方法列表的參數(shù)。 比如,你可以像這樣寫(xiě)一個(gè)返回一些數(shù)據(jù)的非常簡(jiǎn)單的視圖。

from rest_framework.decorators import api_view

@api_view()
def hello_world(request):
    return Response({"message": "Hello, world!"})

這個(gè)視圖會(huì)使用settings中指定的默認(rèn)的渲染器,解析器,認(rèn)證類(lèi)等等。

默認(rèn)的情況下,只有GET請(qǐng)求會(huì)被接受。其他的請(qǐng)求方法會(huì)得到一個(gè)"405 Method Not Allowed"響應(yīng)??梢韵裣旅娴氖纠a一樣改變默認(rèn)行為:

@api_view(['GET', 'POST'])
def hello_world(request):
    if request.method == 'POST':
        return Response({"message": "Got some data!", "data": request.data})
    return Response({"message": "Hello, world!"})

你也可以用exclude_from_schema參數(shù)標(biāo)記API視圖來(lái)忽略任何自動(dòng)生成的視圖,

@api_view(['GET'], exclude_from_schema=True)
def api_docs(request):
    ...

API 策略裝飾器

REST framework提供了一組可以加到視圖上的裝飾器來(lái)重寫(xiě)默認(rèn)設(shè)置。這些裝飾器必須放在@api_view的后(下)面。比如,要?jiǎng)?chuàng)建一個(gè)使用限制器確保特定用戶(hù)每天只能調(diào)用一次的視圖,可以用@throttle_classes裝飾器并給它傳遞一個(gè)限制器類(lèi)的列表。

from rest_framework.decorators import api_view, throttle_classes
from rest_framework.throttling import UserRateThrottle

class OncePerDayUserThrottle(UserRateThrottle):
        rate = '1/day'

@api_view(['GET'])
@throttle_classes([OncePerDayUserThrottle])
def view(request):
    return Response({"message": "Hello for today! See you tomorrow!"})

這些裝飾器和上文中的APIView的子類(lèi)中設(shè)置的屬性相對(duì)應(yīng)。

可用的裝飾器有:

  • @renderer_classes(...)
  • @parser_classes(...)
  • @authentication_classes(...)
  • @throttle_classes(...)
  • @permission_classes(...)

這些裝飾器中的每一個(gè)都接受一個(gè)參數(shù),這個(gè)參數(shù)必須是類(lèi)的列表或元組。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)