一幢妄、基本視圖類 (APIView/@api_view)
1通砍、類基礎(chǔ)視圖(APIView)
DRF不同于django常規(guī)的view類拥峦,他有如下幾點(diǎn)優(yōu)點(diǎn):
* 提供了更好用的request對象黔寇,不同于普通的django HttpRequest更好用镜粤。
* 封裝了Response對象,代替了原有的django HttpResponse髓需,視圖將管理內(nèi)容協(xié)商并設(shè)置正確的渲染器的響應(yīng)许师。
* 任何APIException異常將會(huì)被捕捉,并做適當(dāng)?shù)捻憫?yīng)。
* 傳入的請求將身份驗(yàn)證和適當(dāng)?shù)臋?quán)限和節(jié)流檢查將之前運(yùn)行調(diào)度請求處理程序的方法微渠。
一個(gè)小例子:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authenication, permissions
class ListUser(APIView):
“””
展示系統(tǒng)中所有的用戶
* 需要令牌認(rèn)證搭幻。
* 只有admin用戶能夠訪問這一個(gè)視圖
"""
authentication_classes = (authentication.TokenAuthentication,) # 認(rèn)證策略屬性
permission_classes = (permissions.IsAdminUser,) # 權(quán)限策略屬性
def get(self, requeset, format=None):
"""
返回一個(gè)用戶列表
"""
usernames = [user.username for user in User.objects.all()]
return Response(usernames)
1) API策略屬性
以下的API策略屬性應(yīng)用于APIView,控制視圖的策略:
renderer_classes: 渲染器類
parser_classes: 解釋器類
authentication_classes: 權(quán)限類
throttle_classes:節(jié)流類
permission_classes: 權(quán)限類
content_negotiation_class: 內(nèi)容協(xié)商類
2)API 策略方法
以下的策略方法用在API的策略逞盆,通常不用重寫它:
get_renderers(self): 獲取渲染器方法
get_parsers(self): 獲取解釋器方法
get_authenticators(self): 或缺認(rèn)證方法
get_throttles(self): 獲取節(jié)流方法
get_permissions(self): 獲取權(quán)限方法
get_content_negotiator(self): 獲取內(nèi)容協(xié)商方法
3)API策略實(shí)施方法
下列方法之前被稱為調(diào)度處理程序方法:
check_permissions(self, request): 檢查權(quán)限
check_throttles(self, request): 檢查節(jié)流
check_content_negotiation(self, request, force=False): 檢查內(nèi)容協(xié)商
4)調(diào)度方法
這些執(zhí)行任何操作,需要發(fā)生之前或之后調(diào)用處理程序方法等.
initial(self, request, *args, **kwargs): 執(zhí)行任何操作,需要發(fā)生在處理程序方法之前被調(diào)用檀蹋。這個(gè)方法是用來執(zhí)行權(quán)限和節(jié)流,并執(zhí)行內(nèi)容協(xié)商。
handle_exception(self, exc):拋出的任何異常處理程序方法將被傳遞給這個(gè)方法,而返回響應(yīng)實(shí)例,或者re-raises異常云芦。
initialize_request(self, request, *args, **kwargs):確保請求對象傳遞給處理程序方法是request的一個(gè)實(shí)例俯逾,而不是django的HttpRequest
finalize_response(self, request, response, *args, **kwargs):確保任何響應(yīng)處理程序方法返回的對象將被呈現(xiàn)到正確的內(nèi)容類型
2、函數(shù)基礎(chǔ)視圖(@api_view())
DRF同樣提供了另外一種函數(shù)基礎(chǔ)視圖來裝飾django的普通視圖舅逸,我們同樣可以使用request來接受請求和response響應(yīng)桌肴。
一個(gè)小例子:
from rest_framework.decorators import api_view
@api_view
def hello_world(request):
return Response({“message”:”Hello world!”})
1)api_view()使用方法
這個(gè)視圖將使用默認(rèn)渲染器、解析器琉历、身份驗(yàn)證設(shè)置中指定的類等坠七。通常默認(rèn)只有GET方法,其他請求方法會(huì)報(bào)405錯(cuò)誤旗笔,我們可以手動(dòng)添加方法為這
裝飾器指定request方法彪置。像這樣:
@api_view([‘GET’, ‘POST’])
def hello_world(request):
if request.method == ‘POST’:
return Response({“message”:”Got some data”, “data”: request.data})
return Response({“messsage”:”Hello world!”})
2)API策略裝飾器
DRF提供了很多附加的裝飾器,我們可以添加到@api_view()后面蝇恶,例如要加入一個(gè)節(jié)流的裝飾器來確保特定用戶每天只能一次通過這個(gè)視圖拳魁,我
我們就要用到@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 to day! see you tomorrow!”})
其他可用API的裝飾器:
@renderer_classes(…)
@parser_classes(…)
@authentication_classes(…)
@throttle_classes(…)
@permission_classes(…)
二、 通用視圖(Generic views)
基于類視圖的主要好處之一是他們允許您編寫可重用的行為.
REST框架提供的通用視圖允許您快速構(gòu)建API觀點(diǎn)緊密地映射到您的數(shù)據(jù)庫模型.
如果通用視圖不適合你的需要API,您可以使用常規(guī)APIView類,或重用mixin和基類使用的通用視圖來組成自己的組可重用通用視圖艘包。
1的猛、通用視圖
同樣我們可以設(shè)置一些類屬性在通用視圖內(nèi)耀盗,也可以根據(jù)特殊要寫重寫它的內(nèi)部視圖方法想虎。一個(gè)小例子:
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from rest_framework.permissions import IsAdminUser
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)
def list(self, request):
# Note the use of get_queryset() instead of self.queryset
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
在urls配置中,我們可以使用.as_views()來轉(zhuǎn)換成視圖函數(shù)叛拷,當(dāng)然也可以配置一些屬性
url(r’^/users/’, ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name=’user-list’)
2舌厨、GenericAPIView通用視圖API參考:
GenericAPIView繼承了DRF的APIView類,為list和detail視圖增加了一些一般需求行為方法(提供queryset)忿薇。
1)屬性
基本屬性:
queryset: 用于返回query對象集合裙椭,也可以使用get_queryset()方法。
serializer_class: 序列化器類,應(yīng)該用于輸入進(jìn)行驗(yàn)證和反序列化,并用于序列化輸出署浩。通常情況下,你必須設(shè)置這個(gè)屬性,或重寫get_serializer_class()方法揉燃。
lookup_field: 模型的字段應(yīng)該用于執(zhí)行對象查找個(gè)別的模型實(shí)例
lookup_url_kwarg:URL應(yīng)該用于對象查找關(guān)鍵字參數(shù)
分頁屬性:
pagination_class: 用于返回一個(gè)分頁列表視圖的分頁類,默認(rèn)與settings中設(shè)置的DEFAULT_PAGINATION_CLASS 值相同筋栋,
可以通過’rest_framework.pagination.PageNumberPagination’設(shè)置分頁數(shù)
過濾器屬性:
filter_backends: 過濾queryset的類列表炊汤,和在settings中設(shè)置DEFAULT_FILTER_BACKENDS 一樣
2)方法
基本方法:
get_queryset(): 返回queryset。(詳情見官網(wǎng)http://www.django-rest-framework.org/api-guide/generic-views/)
get_object():獲取某一個(gè)具體的model實(shí)例對象。
保存與刪除掛鉤方法:
以下方法是mixins類提供抢腐,提供簡單的對象保存和刪除的行為重寫:
perform_create(self, serializer): CreateModelMixin 當(dāng)要保存對象時(shí)候會(huì)被調(diào)用
perform_update(self, serializer):UpdateModelMixin 當(dāng)要更新對象時(shí)候會(huì)被調(diào)用
perform_destroy(self, instance): DestoryModelMixin 當(dāng)藥刪除對象時(shí)候會(huì)被調(diào)用
3)姑曙、Mixins
mixin類提供用于提供基礎(chǔ)視圖的操作行為。注意,mixin類提供操作方法而不是定義處理程序方法,比如. get()和. post(),直接迈倍。這允許更靈活的組合的行為伤靠。
通過rest_framework.mixins引用。
ListModelMixin:提供list方法啼染,列出queryset
CreateModelMixin: 提供create方法宴合,創(chuàng)建和保存一個(gè)Model對象
RetrieveModelMixin:提供retrieve方法,檢索一個(gè)存在的model對象
UpdateModelMixin: 提供Update方法提完,更改一個(gè)模型對象
DestroyModelMixin:提供destroy方法形纺,刪除一個(gè)模型對象
4)Generic
Generic通用視圖類提供具體操作的通用視圖類,可以理解為Generic.GenericAPIView和mixin類的合體徒欣,通過rest_framework.generic.調(diào)用
.CreateAPIView:
創(chuàng)建一個(gè)模型實(shí)例
提供post方法的處理器
繼承于:GenericAPIView逐样,CreateModelMixin
.ListAPIView:
模型實(shí)例的集合
提供get方法處理器
繼承于:GenericAPIView,ListModelMixin
.RetrieveAPIView:
一個(gè)模型實(shí)例
提供get方法處理器
繼承于:GenericAPIView打肝,RetrieveModelMixin
.DestoryAPIView:
刪除一個(gè)模型實(shí)例
提供delete方法處理器
繼承于:GenericAPIView脂新,DestroyModelMixin
.UpdateAPIView:
修改模型實(shí)例,
提供put和patch方法處理器
繼承于:GenericAPIView粗梭,UpdateModelMixin
.ListCreateAPIView:
創(chuàng)建和展示一個(gè)模型實(shí)例集合
提供get和post處理器
繼承于:GenericAPIView争便,ListModelMixin,CreateModelMixin
.RetrieveUpdateAPIView:
讀和改一個(gè)模型實(shí)例
提供get,put,patch處理器
繼承于:GenericAPIView断医,RetrieveModelMixin滞乙,UpdateModelMixin
.RetrieveDestoryAPIView:
讀和刪除一個(gè)模型實(shí)例
提供get和delete處理器
繼承于:GenericAPIView,RetrieveModelMixin鉴嗤,DestroyModelMixin
.RetrieveUpdateDestroyAPIView:
讀斩启、改和刪一個(gè)模型實(shí)例
get, put, patch,delete處理器
繼承于:GenericAPIView,RetrieveModelMixin醉锅,UpdateModelMixin兔簇,DestroyModelMixin
三、視圖集合ViewSets
Django REST框架允許您將一組相關(guān)的邏輯視圖在一個(gè)類硬耍,ViewSet類是一個(gè)簡單類型的基于類的觀點(diǎn),沒有提供任何方法處理程序如.get()或. post(),
而代替提供方法比如.list()和create()垄琐。
一個(gè)小例子:
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from myapps.serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.response import Response
class UserViewSet(viewsets.ViewSet):
“””
A simple ViewSet for listing or retrieving users.
“””
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = User.objects.all()
user = get_object_or_404(queryset, pk=pk)
serializer = UserSerializer(user)
return Response(serializer.data)
1).關(guān)于ViewSets
如果我們需要,我們需要為兩個(gè)GET請求分開綁定視圖:
user_list = UserViewSet.as_view({“GET”:’list’})
user_detail = UserViewSet.as_view({‘GET’:’retrieve’})
但是通常我們不會(huì)這樣做经柴,而是通過注冊路由來配置url:
from myapp.views import UserViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r’users’, UserViewSet)
urlpatterns = router.urls
或許你會(huì)經(jīng)常用到自己模型數(shù)據(jù)狸窘,而不是手動(dòng)寫視圖集合,這樣就要用到模型視圖集合ModelViewSet:
class UserViewSet(viewsets.ModelViewSet):
“””
A viewset for viewing and editing user instance
“””
serializer_class = UserSerializer
queryset = User.objects.all()
其他路由函數(shù)方法:
class UserViewSet(viewsets.ViewSet):
“””
Example empty viewset demonstrating the standard
actions that will be handled by a router class.
If you’re using format suffixes, make sure to also include
the format=None keyword argument for each action.
“””
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
如果你有特別的需要被路由到的方法,可以將它們標(biāo)記為需要路由使用@detail_route或@list_route修飾符坯认。
@detail_route(methods=[‘post’], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
…
可以通過訪問^users/{pk}/set_password/$來訪問改視圖
2)ViewSets的API參考
.ViewSet:
繼承了APIView翻擒,你可以使用一些標(biāo)準(zhǔn)的屬性例如permission_class,authentication_classes去對視圖做一些策略介杆。ViewSet同樣不提供具體
行為方法的實(shí)現(xiàn),你可以重寫和定義一些請求處理方法韭寸。而代替了原來APIVIew的POST春哨,GET等方法,取而代之的是list恩伺,create等方法赴背。
.GenericViewSet:
繼承了GenericAPIView,提供了默認(rèn)的get_queryset()和get_object()等方法來獲取model數(shù)據(jù)晶渠,但不提供任何請求處理方法凰荚。
.ModelViewSet:
繼承了GenericAPIView,增加了一些請求處理方法褒脯,如list(), retrieve(),create()等便瑟。
例子:
class AccountViewSet(viewsets.ModelViewSet):
“””
A simple ViewSet for viewing and editing accounts
“””
queryset = Account.objects.all()
serializer_class = AccountSerializer
permissions_classes = [IsAccountAdminOrReadOnly]
.ReadOnlyModelViewSet:
繼承了GenericAPIView,只增加了只讀的請求處理方法list()和retrieve()
自定義View類:
只需要繼承GenericAPIView, 增加mixins的相關(guān)處理方法番川。如:
class CreatListRetrieveViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
View.GenericViewSet):
pass