Django-Restful-Framework-常用視圖

通用視圖

drf 基于類的視圖允許我們編寫可重復(fù)使用的模式,并且提供了大量常用視圖及其常用模式,運用各類常用視圖可以快速構(gòu)建緊密映射到數(shù)據(jù)庫的 API 視圖,而如果視圖不符合我們的需求,可以繼承于常規(guī)的 APIView 類,自行擴展。

在使用通用試圖時,我們需要設(shè)置幾個屬性,如下:

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,)

若我們想要重寫視圖類的各種方法,可以如下:

class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (IsAdminUser,)

    def list(self, request):
        # 注意使用`get_queryset()`而不是`self.queryset`
        queryset = self.get_queryset()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

甚至,可以通過 .as_view() 方法傳遞類屬性,這樣連視圖類都不用寫了

url(r'^/users/', ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name='user-list')

GenericAPIView

GenericAPIView 類繼承于APIView類,添加了常見行為
內(nèi)置的每一個通用試圖都是通過將GenericAPIView 類和一個或多個 minxin 類相互結(jié)合來構(gòu)建的

基本設(shè)置

如上所述,我們需要在視圖類中添加屬性控制視圖的行為:

  • queryset,從此視圖返回對象的查詢集。通常必須設(shè)置此屬性,或者通過調(diào)用 get_queryset() 方法覆蓋
  • serializer_class,用于驗證和反序列化輸入以及序列化輸出的序列化類。通常必須設(shè)置,或者調(diào)用get_serializer_class()方法覆蓋
  • lookup_field,用于執(zhí)行各個模型實例的對象查找的模型字段。默認為'pk'
  • lookup_url_kwarg,用于對象查找的 URL 關(guān)鍵字參數(shù)。URL conf 應(yīng)該包含與此值相對應(yīng)的關(guān)鍵字參數(shù)。如果未設(shè)置,則默認使用與lookup_field相同的值

分頁

pagination_class 對列表進行分頁時使用的分頁類。默認值與DEFAULT_PAGINATION_CLASS設(shè)置相同,設(shè)置pagination_class = None將禁用此視圖的分頁

過濾

filter_backends 用于過濾查詢集的過濾器類的列表。默認值與DEFAULT_FILTER_CLASS設(shè)置相同

方法

get_queryset(self)
返回列表視圖的查詢集,并應(yīng)該將其用作查看詳細視圖的基礎(chǔ)。默認返回由 queryset 屬性指定的查詢集
應(yīng)該始終使用此方法, 而不是直接訪問 self.queryset,因為 REST 會在內(nèi)部對 self.queryset 的結(jié)果進行緩存用于后續(xù)所有請求

get_object(self)
返回詳細視圖的對象實例。默認使用lookup_field參數(shù)來過濾基本查詢集

可以覆蓋重寫以提供更復(fù)雜的行為,例如基于多個 URL kwarg 的對象查找,如:

def get_object(self):
    queryset=self.get_queryset()
    filter={}
    for field in self.multiple_lookup_fields:
        filter[field]=self.kwargs[field]

    obj=get_object_or_404(queryset,**filter)
    self.check_object_permissions(self.request,obj)
    return obj

filter_queryset(self,queryset)
給定一個查詢集,使用過濾器進行過濾,返回一個新的查詢集,如下:

def filter_queryset(self,queryset):
    filter_backends=(CategoryFilter,)

    if 'geo_route' in self.request.query_params:
        filter_backends=(GeoRouteFilter,CategoryFilter)
    elif 'geo_point' in self.request.query_params:
        filter_backends=(GeoPointFilter,CategoryFilter)

    for backend in list(filter_backends):
        queryset=backend.filter_queryset(self.request,queryset,view=self)

    return queryset

get_serializer_class(self)
返回用以序列化的類,默認返回serializer_class屬性

可以覆蓋重寫以提供動態(tài)行為,例如使用不同的序列化器進行讀寫操作,或為不同類型的用戶提供不同的序列化器

例子:

def get_serializer_class(self):
    if self.request.user.is_staff:
        return FullAccountSerializer
    return BasicAccountSerializer

保存和刪除鉤子

以下方法由 mixin 類提供,可以很輕松地重寫對象的保存和刪除行為

  • perform_create(self,serializer),保存新對象實例時由CreateModelMixin調(diào)用
  • perform_update(self,serializer),保存現(xiàn)有對象實例時由UpdateModelMixin調(diào)用
  • perform_destroy(self,serializer),刪除對象實例時由DestroyModelMixin調(diào)用

這些鉤子對設(shè)置請求中隱含的但不屬于請求數(shù)據(jù)的屬性特別有用。例如,可以根據(jù)請求用戶或基于 URL 關(guān)鍵字參數(shù)在對象上設(shè)置屬性

def perform_create(self,serializer):
    serializer.save(user=self.request.user)

這些鉤子的覆蓋對于添加保存對象之前或之后發(fā)生的行為(如發(fā)送確認電子郵件或記錄更新)也特別有用

def perform_create(self,serializer):
    queryset=SignRequest.object.filter(user=self.request.user):
    if queryset.exists():
        raise ValidationError('You have already signed up')
    serializer.save(user=self.request.user)

Mixins

mixins 類用于提供基本視圖行為的操作。mixin類提供操作方法,而不是直接定義處理方法,通過rest_framework.mixins導(dǎo)入

ListModelMixin

提供一個.list(request,*args,**kwargs)方法,實現(xiàn)列出一個查詢集

如果查詢集已填充,則返回200 OK響應(yīng),并將 queryset 的序列化表示形式作為響應(yīng)的主體

CreateModelMixin

提供.create(request,*arg,**kwargs)方法,實現(xiàn)創(chuàng)建和保存新模型數(shù)據(jù)實例

如果創(chuàng)建了一個對象,則會返回一個201 Created響應(yīng),并將該對象的序列化表示形式作為響應(yīng)的主體
如果為創(chuàng)建對象提供的請求數(shù)據(jù)無效,則將返回400 Bad Request響應(yīng),并將錯誤細節(jié)作為響應(yīng)的主體

RetrieveModelMixin

提供.retrieve(request,*args,**kwargs)方法,該方法實現(xiàn)在響應(yīng)中返回現(xiàn)有的模型實例

如果可以獲取對象,則返回200 OK響應(yīng),并將對象的序列化表示為響應(yīng)的主體。否則,將返回一個404 Not Found

UpdateModelMixin

提供.update(request,*args,**kwargs)方法,實現(xiàn)更新和保存現(xiàn)有模型實例。還提供了一個 .partial_update(request, *args, **kwargs) 方法,它與更新方法類似,只是更新的所有字段都是可選的。這允許支持 HTTP PATCH 請求。

如果成功更新對象,則返回 200 OK 響應(yīng),并將對象的序列化表示形式作為響應(yīng)的主體
如果提供的用于更新對象的請求數(shù)據(jù)無效,則將返回 400 Bad Request 響應(yīng),并將錯誤細節(jié)作為響應(yīng)的主體

DestroyModelMixin

提供一個 .destroy(request, *args, **kwargs) 方法,實現(xiàn)現(xiàn)有模型實例的刪除

如果一個對象被刪除,則返回一個 204 No Content ,否則它將返回一個 404 Not Found

內(nèi)置視圖類

以下類是具體的通用試圖,從rest_framework.generics導(dǎo)入

CreateAPIView

僅用于創(chuàng)建實例,提供一個post請求的處理方法
繼承自:GenericAPIView,CreateModelMixin

ListAPIView

僅用于讀取模型實例列表,提供一個get請求的處理方法
繼承自:GenericAPIView,ListModelMixin

RetrieveAPIView

僅用于查詢單個模型實例,提供一個get請求的處理方法
繼承自:GenericAPIView,RetrieveModelMixin

DestroyAPIView

僅用于刪除單個模型實例,提供一個delete請求的處理方法
繼承其:GenericAPIView, DestroyModelMixin

UpdateAPIView

僅用于更新單個模型實例,提供 putpatch 請求的處理方法
繼承自: GenericAPIView, UpdateModelMixin

ListCreateAPIView

既可以獲取也可以實例集合,也可以創(chuàng)建實例列表,提供 getpost 請求的處理方法
繼承自: GenericAPIView, ListModelMixinCreateModelMixin

RetrieveUpdateAPIView

既可以查詢也可以更新單個實例,提供 get,putpatch 請求的處理方法
繼承自: GenericAPIView, RetrieveModelMixin,UpdateModelMixin

RetrieveDestroyAPIView

既可以查詢也可以刪除單個實例,提供 getdelete 請求的處理方法
繼承自: GenericAPIView, RetrieveModelMixinDestroyModelMixin

RetrieveUpdateDestroyAPIView

同時支持查詢,更新,刪除,提供 getput,patchdelete 請求的處理方法
繼承自: GenericAPIView, RetrieveModelMixin,UpdateModelMixinDestroyModelMixin

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容