Django REST framework-API指南04-Generic views 原創翻譯

python技術交流羣332680349,資源分享,技術交流。

類的視圖

Django的類視圖…被開發爲常見使用模式的快捷方式…他們採取在視圖開發中發現的一些常見習語和模式,並將其抽象出來,以便您可以快速編寫數據的常見視圖,而無需重複。
—-Django文檔

基於類視圖的主要優點之一是它們允許您組合可重用行爲的方式。REST框架來利用這個優勢,通過提供許多提供常用模式的預構建視圖。

REST框架提供的類視圖允許您快速構建與數據庫模型緊密對應的API視圖。

如果類視圖不符合您的API需求,則APIView可以使用常規類,或者重用類視圖使用的mixins和base類來構建您自己的一組可重用的類視圖。

例子

通常當使用類視圖時,您將覆蓋視圖,並設置幾個類屬性。

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):
        # Note the use of `get_queryset()` instead of `self.queryset`
        queryset = self.get_queryset()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

對於非常簡單的情況,您可能希望使用該.as_view()方法傳遞任何類屬性。例如,您的URLconf可能包含以下條目:

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

API參考

類的API視圖

此類擴展了REST框架的APIView類,爲標準列表和詳細視圖添加了常見的請求行爲。
提供的每個具體類視圖是通過GenericAPIView與一個或多個mixin類組合來構建的。

屬性

基本設置:

以下屬性控制基本視圖行爲。

  • queryset - 用於從此視圖返回對象的查詢器集。通常,您必須設置此屬性,或覆蓋該get_queryset()方法。如果您覆蓋了一個視圖方法,那麼重要的是您需要get_queryset()代替直接訪問此屬性,而是調用queryset一次,並且將爲所有後續請求緩存那些結果。

  • serializer_class - 用於驗證和反序列化輸入以及序列化輸出的serializer類。通常,您必須設置此屬性,或覆蓋該get_serializer_class()方法。

  • lookup_field - 應用於執行單個模型實例的對象查找的模型字段。默認爲’pk’。請注意,使用超鏈接的API時,您需要確保API視圖和串行類設置查找字段,如果你需要使用一個自定義值。

  • lookup_url_kwarg - 應該用於對象查找的URL關鍵字參數。URL conf應包含與該值對應的關鍵字參數。如果取消設置,則默認使用與之相同的值lookup_field。

分頁:

當與列表視圖一起使用時,以下屬性用於控制分頁。

pagination_class - 有分頁列表結果時應使用的分頁類。默認值與DEFAULT_PAGINATION_CLASS設置值相同’rest_framework.pagination.PageNumberPagination’。設置pagination_class=None將在此視圖上禁用分頁。

過濾:

filter_backends - 應用於過濾查詢集的過濾器後端類的列表。默認值與DEFAULT_FILTER_BACKENDS設置相同。

方法

基本方法:

get_queryset(self)

返回應該用於列表視圖的查詢集,並且應該將其用作查看詳細視圖的基礎。默認返回queryset屬性指定的查詢集。

應始終使用此方法,而不是self.queryset直接訪問,因爲self.queryset只得到一次評估,並且爲所有後續請求緩存這些結果。

可能會被覆蓋以提供動態行爲,例如返回特定於發出請求的用戶的查詢集。

例如:

def get_queryset(self):
    user = self.request.user
    return user.accounts.all()
get_object(self)

返回應用於詳細視圖的對象實例。默認使用lookup_field參數過濾基本查詢集。

可能會被覆蓋以提供更復雜的行爲,例如基於多個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

請注意,如果您的API不包括任何對象級權限,則可以選擇性地排除self.check_object_permissions該對象,並簡單地從get_object_or_404查找返回對象。

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屬性。

可能會被覆蓋以提供動態行爲,例如使用不同的串行器進行讀寫操作,或爲不同類型的用戶提供不同的序列化程序。

例如:

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

保存和刪除鉤子:

以下方法由mixin類提供,並提供容易覆蓋對象保存或刪除行爲。

  • perform_create(self, serializer)- CreateModelMixin保存新對象實例時調用。
  • perform_update(self, serializer)- UpdateModelMixin保存現有對象實例時調用。
  • perform_destroy(self, instance)- DestroyModelMixin刪除對象實例時調用。
    這些鉤子特別適用於設置請求中隱性的屬性,但不是請求數據的一部分。例如,您可以根據請求用戶或基於URL關鍵字參數在對象上設置屬性。
def perform_create(self, serializer):
    serializer.save(user=self.request.user)

這些覆蓋點對於添加在保存對象之前或之後發生的行爲(例如發送確認或記錄更新)也特別有用。

def perform_update(self, serializer):
    instance = serializer.save()
    send_email_confirmation(user=self.request.user, modified=instance)

您也可以使用這些鉤子來提供額外的驗證,通過ValidationError()。如果您需要在數據庫保存時應用一些驗證邏輯,這將非常有用。例如:

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

注意:這些方法取代舊式的2.x版pre_save,post_save,pre_delete和post_delete方法,這將不再可用。

其他方法:

通常您不需要覆蓋以下方法,儘管你可能需要調用他們,如果你用GenericAPIView寫一個自定義視圖。

  • get_serializer_context(self) - 返回包含應提供給序列化程序的任何額外上下文的字典。默認爲包括’request’,’view’和’format’鍵。
  • get_serializer(self, instance=None, data=None, many=False, partial=False) - 返回一個序列化器實例。
  • get_paginated_response(self, data)- 返回分頁樣式Response對象。
  • paginate_queryset(self, queryset)- 如果需要,分頁查詢集,返回頁面對象,或者None如果未爲此視圖配置分頁。
  • filter_queryset(self, queryset) - 給定一個查詢集,使用任何過濾器後端進行過濾,返回一個新的查詢集。

Mixins

mixin類提供用於提供基本視圖行爲的操作。請注意,mixin類提供操作方法,而不是定義處理程序方法,例如像.get()和.post(),直接。這樣可以更靈活地組合行爲。

可以從rest_framework.mixins中導入mixin類。

ListModelMixin

提供一種.list(request, *args, **kwargs)實現列出查詢集的方法。
如果查詢集被填充,則返回一個200 OK響應,其中序列化的展示作爲響應的主體。響應數據可以可選地被分頁。

CreateModelMixin

提供.create(request, *args, **kwargs)一種實現創建和保存新模型實例的方法。
如果創建一個對象,則返回一個201 Created響應,該對象的序列化展示作爲響應的主體。如果表示包含一個命名url的鍵,則響應的Location 頭將被填充用該值。
如果提供用於創建對象的請求數據無效,400 Bad Request則將返回響應,其中錯誤詳細信息作爲響應的正文。

RetrieveModelMixin

提供一種.retrieve(request, *args, **kwargs)在響應中實現返回現有模型實例的方法。
如果可以檢索到對象,則返回一個200 OK響應,並將對象的序列化表述作爲響應的正文。否則會返回404 Not Found.

UpdateModelMixin

提供一種.update(request, *args, **kwargs)實現更新和保存現有模型實例的方法。
還提供了.partial_update(request, *args, **kwargs)一種類似於update方法的方法,但更新的所有字段將是可選的。這允許支持HTTP PATCH請求。
如果一個對象被更新,則返回一個200 OK響應,該對象的序列化表述作爲響應的主體。
如果提供用於更新對象的請求數據無效,400 Bad Request則將返回響應,錯誤詳細信息作爲響應的正文。

DestroyModelMixin

提供一種.destroy(request, *args, **kwargs)實現對現有模型實例的刪除的方法。
如果對象被刪除,則返回一個204 No Content響應,否則返回一個404 Not Found。

具體的視圖類

以下類是具體的通用視圖。如果您使用類視圖,這通常是您將要工作的級別,除非您需要大量自定義的行爲。
視圖類可以從中導入rest_framework.generics。

CreateAPIView

用於僅創建端點。
提供一個post方法處理程序
擴展:GenericAPIView,CreateModelMixin

ListAPIView

用於只讀端點來表述模型實例的集合。
提供一個get方法處理程序
擴展:GenericAPIView,ListModelMixin

RetrieveAPIView

用於只讀端點來表示單一模型實例。
提供一個get方法處理程序
擴展:GenericAPIView,RetrieveModelMixin

DestroyAPIView

用於單一模型實例的僅刪除端點。
提供一個delete方法處理程序
擴展:GenericAPIView,DestroyModelMixin

UpdateAPIView

用於單一模型實例的僅更新端點。
提供put和patch方法處理程序。
擴展:GenericAPIView,UpdateModelMixin

ListCreateAPIView

用於讀寫端點來表示模型實例的集合。
提供get和post方法處理程序。
擴展:GenericAPIView,ListModelMixin,CreateModelMixin

RetrieveUpdateAPIView

用於讀取或更新端點以表示單一模型實例。
提供get,put並且patch方法處理。
擴展:GenericAPIView,RetrieveModelMixin,UpdateModelMixin

RetrieveDestroyAPIView

用於讀取或刪除端點以表示單一模型實例。
提供get和delete方法處理程序。
擴展:GenericAPIView,RetrieveModelMixin,DestroyModelMixin

RetrieveUpdateDestroyAPIView

用於讀寫刪除端點來表示單一模型實例。
提供get,put,patch和delete方法處理。
擴展:GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin

自定義通用的視圖

通常,您將需要使用現有的類視圖,但使用一些稍微自定義的行爲。如果您發現自己在多個地方重複使用一些自定義行爲,您可能需要將行爲重構爲通用類,然後可以根據需要將其應用於任何視圖集合或視圖。

創建自定義mixins

例如,如果您需要根據URL conf中的多個字段查找對象,則可以創建一個類似如下的mixin類:

class MultipleFieldLookupMixin(object):
    """
    Apply this mixin to any view or viewset to get multiple field filtering
    based on a `lookup_fields` attribute, instead of the default single field filtering.
    """
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            if self.kwargs[field]: # Ignore empty fields.
                filter[field] = self.kwargs[field]
        obj = get_object_or_404(queryset, **filter)  # Lookup the object
        self.check_object_permissions(self.request, obj)
        return obj

然後,只要您需要應用自定義行爲,就可以簡單地將此mixin應用於視圖集合或視圖。

class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_fields = ('account', 'username')

如果您需要使用自定義行爲,則使用自定義mixins是一個很好的選擇。

創建自定義基類

如果您在多個視圖中使用mixin,您可以進一步瞭解並創建自己的一組基本視圖,然後可以在整個項目中使用。例如:

class BaseRetrieveView(MultipleFieldLookupMixin,
                       generics.RetrieveAPIView):
    pass

class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
                                    generics.RetrieveUpdateDestroyAPIView):
    pass

使用自定義基類是一個很好的選擇,如果您有自定義行爲,始終需要在整個項目中的大量視圖中重複。

PUT作爲創建

在版本3.0之前,將REST框架混合體視爲PUT更新或創建操作,具體取決於對象是否已存在。
允許PUT作爲創建操作是有問題的,因爲它必然暴露關於對象的存在或不存在的信息。透明地允許重新創建先前刪除的實例也不是一個更好的默認行爲,而不僅僅是返回404響應。
兩種樣式“ PUT作爲404”和“ PUT作爲創建”可以在不同的情況下有效,但從3.0版起,我們現在使用404行爲作爲默認值,因爲它更簡單和更明顯。
如果您需要通用的PUT-as-create行爲,您可能希望將類似這樣的AllowPUTAsCreateMixin類包含爲您的視圖的混合。

三方庫

以下第三方軟件包提供了其他類視圖實現。

Django REST Framework bulk

在Django的REST的架構,bulk實現通用視圖mixins以及一些普通具體類視圖允許通過API請求應用批量操作。

Django Rest Multiple Models

Django Rest多個模型提供類視圖(和mixin),用於通過單個API請求發送多個序列化模型和/或查詢集。

發佈了48 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章