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請求發送多個序列化模型和/或查詢集。