API Guide(三)之Views
Class-based Views
Django‘s class-based views are a welcome departure from the old-style views.
- Reinout van Rees
REST框架提供了一個APIView
類,which subclasses Django‘s View
class.
APIView
類與普通View
類有以下不同:
- 傳遞給the handler methods 的Requests 將是REST框架的
Request
實例,而不是Django的HttpRequest
實例。 - Handler methods 可能返回REST框架的
Response
HttpResponse
。該視圖將管理 content negotiation並根據響應設置正確的渲染器。 - 任何
APIException
異常都將被捕獲並被調解為適當的響應。 - 在請求發送到處理程序方法之前,傳入請求將被認證,並運行適當的permission and/or throttle checks。
使用APIView
類與常規View
類一樣,像往常一樣,傳入的請求被調度到適當的處理程序方法,例如.get()
或.post()
。另外,可以在控制API策略的各個方面的類上設置許多屬性。
例如:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import authentication, permissions class ListUsers(APIView): """ View to list all users in the system. * Requires token authentication. * Only admin users are able to access this view. """ 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視圖的 the pluggable aspects。
.renderer_classes
.parser_classes
.authentication_classes
.throttle_classes
.permission_classes
.content_negotiation_class
API策略的實例化方法
REST框架使用以下方法來實例化各種可插拔API策略。通常不需要覆蓋這些方法。
.get_renderers(self)
.get_parsers(self)
.get_authenticators(self)
.get_throttles(self)
.get_permissions(self)
.get_content_negotiator(self)
.get_exception_handler(self)
API策略的實施方法
調度到處理程序方法之前調用以下方法。
.check_permissions(self,request)
.check_throttles(self,request)
.perform_content_negotiation(self,request,force = False)
調度方式
以下方法由視圖的.dispatch()
方法直接調用。這些方法執行任何需要在.get()
,.post()
,put()
,patch()
和.delete()
等handler methods調用之前或之後發生的操作。
.initial(self,request,* args,** kwargs)
在調用 the handler method之前執行任何需要發生的操作。此方法用於執行權限和限制,並執行內容協商。
通常您不需要覆蓋此方法。
.handle_exception(self,exc)
the handler method 拋出的任何異常都將傳遞給此方法,該方法返回一個Response
實例,或重新引發異常。
The default implementation 處理任何 rest_framework.exceptions.APIException
的子類,以及Django Http404
和PermissionDenied
異常,並返回適當的錯誤響應。
如果您需要自定制API返回的錯誤響應,則應該對此方法進行子類化。
.initialize_request(self,request,* args,** kwargs)
確保傳遞給handler方法的請求對象是一個 Request
的實例,而不是通常的Django HttpRequest
。
通常您不需要覆蓋此方法。
.finalize_response(self,request,response,* args,** kwargs)
確保從 the handler method返回的任何Response
對象被渲染為 the content negotiation所確定的正確內容類型。
通常您不需要覆蓋此方法。
Function Based Views
CBV不總是最好的解決方案。
- 尼克·考格蘭
REST框架還允許使用常規的FBV。它提供了一組簡單的、綁定到FBV的裝飾器,以確保它們接收到一個Request
實例(而不是通常的Django HttpRequest
實例),並允許它們返回Response
(而不是Django HttpResponse
),還允許您配置請求的處理方式。
@api_view()
簽名: @api_view(http_method_names=[‘GET‘], exclude_from_schema=False)
這個功能的核心是api_view
裝飾器,它提供了一系列視圖應該響應的HTTP方法。例如,這是如何編寫一個非常簡單的、只能手動返回一些數據的視圖:
from rest_framework.decorators import api_view @api_view() def hello_world(request): return Response({"message": "Hello, world!"})
這個視圖將使用在settings中指定的、默認的 renderers, parsers, authentication classes等
默認情況下,只接受GET
方法。其他方法將以“405 Method Not Allowed”進行響應。要更改此行為,請指定視圖允許的方法,如下所示:
@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!"})
You can also mark an API view as being omitted from any auto-generated schema, using the exclude_from_schema
argument.:
@api_view([‘GET‘], exclude_from_schema=True) def api_docs(request): ...
API策略裝飾器
要覆蓋默認設置,REST框架提供了一組其他的可以添加到視圖的裝飾器。這些裝飾器一定要放在的@api_view
裝飾器的下面。例如,要使用 throttle 創建一個每天只能由特定用戶調用一次的視圖,請使用@throttle_classes
裝飾器,passing a list of throttle classes:
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
子類上設置的屬性。
可用的裝飾器是:
@renderer_classes(...)
@parser_classes(...)
@authentication_classes(...)
@throttle_classes(...)
@permission_classes(...)
這些裝飾器中的每一個都需要一個參數,它必須是列表或元組元素。
API Guide(三)之Views