Generic views

基于類的視圖的一個主要優(yōu)點是它們允許你組合可重復(fù)使用的行為巍扛。 REST框架通過提供大量預(yù)構(gòu)建視圖來提供常用模式,從而充分利用了這一點事甜。
REST框架提供的通用視圖允許您快速構(gòu)建緊密映射到數(shù)據(jù)庫模型的API視圖兔沃。
如果通用視圖不適合您的API需求玛迄,則可以下拉使用常規(guī)APIView類狡逢,或者重用通用視圖使用的mixins和基類來組成自己的可重用通用視圖集宁舰。

示例

通常,在使用通用視圖時奢浑,您將覆蓋該視圖蛮艰,并設(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,)

對于更復(fù)雜的情況殷费,您可能還想覆蓋視圖類中的各種方法印荔。例如。

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參考

GenericAPIView

此類擴展了REST框架的APIView類实柠,為標(biāo)準(zhǔn)列表和詳細信息視圖添加了常用的行為。
提供的每個具體通用視圖都是通過將GenericAPIView與一個或多個mixin類組合而構(gòu)建的善涨。

屬性

基本設(shè)置:
以下屬性控制基本視圖行為窒盐。

  • queryset - 應(yīng)該用于從此視圖返回對象的查詢集. 通常,您必須設(shè)置此屬性钢拧,或覆蓋get_queryset()方法蟹漓。如果要覆蓋視圖方法,則必須調(diào)用get_queryset()而不是直接訪問此屬性源内,因為queryset將被評估一次葡粒,并且將為所有后續(xù)請求緩存這些結(jié)果。
  • serializer_class - 應(yīng)該用于驗證和反序列化輸入以及序列化輸出的序列化程序類膜钓。 通常嗽交,您必須設(shè)置此屬性,或覆蓋get_serializer_class()方法颂斜。
  • lookup_field - 應(yīng)該用于執(zhí)行單個模型實例的對象查找的模型字段夫壁。 默認為'pk'。 請注意沃疮,使用超鏈接API時盒让,如果需要使用自定義值梅肤,則需要確保API視圖和序列化程序類都設(shè)置查找字段。
  • lookup_url_kwarg - 應(yīng)該用于對象查找的URL關(guān)鍵字參數(shù)邑茄。 URL conf應(yīng)包含與此值對應(yīng)的關(guān)鍵字參數(shù)姨蝴。 如果未設(shè)置,則默認使用與lookup_field相同的值撩扒。

分頁:
與列表視圖一起使用時似扔,以下屬性用于控制分頁。

  • pagination_clas - 分頁列表結(jié)果時應(yīng)使用的分頁類搓谆。 默認為與DEFAULT_PAGINATION_CLASS設(shè)置相同的值炒辉,即'rest_framework.pagination.PageNumberPagination'。 設(shè)置pagination_class = None將禁用此視圖上的分頁泉手。

過濾:

  • filter_backends - 應(yīng)該用于過濾查詢集的過濾器后端類列表黔寇。默認值與DEFAULT_FILTER_BACKENDS設(shè)置的值相同。

Methods

Base methods:

get_queryset(self)

返回應(yīng)該用于列表視圖的查詢集斩萌,該查詢集應(yīng)該用作詳細視圖中查找的基礎(chǔ)缝裤。默認返回queryset屬性指定的查詢集。
應(yīng)始終使用此方法而不是直接訪問self.queryset颊郎,因為self.queryset僅被評估一次憋飞,并且這些結(jié)果將被緩存用于所有后續(xù)請求。

可以重寫以提供動態(tài)行為姆吭,例如返回查詢集榛做,該查詢集特定于發(fā)出請求的用戶。

例如:

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

get_object(self)

返回應(yīng)該用于詳細視圖的對象實例内狸。 默認使用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

請注意锰瘸,如果您的API不包含任何對象級別權(quán)限,您可以選擇性地排除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)

返回應(yīng)該用于序列化程序的類。 默認返回serializer_class屬性渤涌。

可以重寫以提供動態(tài)行為佩谣,例如使用不同的序列化程序進行讀寫操作,或者為不同類型的用戶提供不同的序列化程序实蓬。

例如:

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

Save and deletion hooks:
mixin類提供了以下方法茸俭,并提供了對象保存或刪除行為的輕松覆蓋吊履。

  • perform_create(self, serializer) - 在保存新對象實例時由CreateModelMixin調(diào)用。
  • perform_update(self, serializer) - 在保存現(xiàn)有對象實例時由UpdateModelMixin調(diào)用调鬓。
  • perform_destroy(self, instance) - 在刪除對象實例時由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_update(self, serializer):
    instance = serializer.save()
    send_email_confirmation(user=self.request.user, modified=instance)

您還可以通過引發(fā)ValidationError()來使用這些鉤子來提供額外的驗證驴娃。如果您需要在數(shù)據(jù)庫保存點應(yīng)用某些驗證邏輯,這可能很有用循集。例如:

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編寫自定義視圖镶柱,則可能需要調(diào)用它們旷档。

  • get_serializer_context(self) - 返回一個字典,其中包含應(yīng)提供給序列化程序的任何額外上下文歇拆。 默認包括“請求”彬犯,“查看”和“格式”鍵。
  • get_serializer(self查吊,instance = None,data = None湖蜕,many = False逻卖,partial = False) - 返回一個序列化程序?qū)嵗?/li>
  • get_paginated_response(self,data) - 返回分頁樣式的Response對象昭抒。
  • paginate_queryset(self评也,queryset) - 如果需要,可以返回一個查詢集灭返,返回頁面對象;如果沒有為此視圖配置分頁盗迟,則為“無”。
  • filter_queryset(self熙含,queryset) - 給定一個查詢集罚缕,使用正在使用的過濾后端進行過濾,返回一個新的查詢集怎静。

Mixins

mixin類提供用于提供基本視圖行為的操作邮弹。 請注意黔衡,mixin類提供了操作方法,而不是直接定義處理程序方法腌乡,例如.get()和.post()盟劫。 這允許更靈活的行為組合。
mixin類可以從rest_framework.mixins導(dǎo)入与纽。

ListModelMixin

提供.list(request侣签,* args,** kwargs)方法急迂,用于實現(xiàn)列出查詢集影所。
如果填充了查詢集,則返回200 OK響應(yīng)袋毙,并將查詢集的序列化表示作為響應(yīng)的主體型檀。 可選地,可以對響應(yīng)數(shù)據(jù)進行分頁听盖。

CreateModelMixin

提供.create(request胀溺,* args,** kwargs)方法皆看,用于實現(xiàn)創(chuàng)建和保存新模型實例仓坞。
如果創(chuàng)建了一個對象,則返回201 Created響應(yīng)腰吟,該對象的序列化表示形式為響應(yīng)的主體无埃。 如果表示包含名為url的鍵,則響應(yīng)的Location標(biāo)頭將填充該值毛雇。
如果為創(chuàng)建對象而提供的請求數(shù)據(jù)無效嫉称,則將返回400 Bad Request響應(yīng),并將錯誤詳細信息作為響應(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)方法,該方法與update方法類似壁查,不同之處在于更新的所有字段都是可選的觉至。 這允許支持HTTP PATCH請求撵幽。
如果對象被更新办成,則返回200 OK響應(yīng)惫搏,并將對象的序列化表示作為響應(yīng)的主體突雪。
如果為更新對象而提供的請求數(shù)據(jù)無效逃沿,則將返回400 Bad Request響應(yīng)腌紧,并將錯誤詳細信息作為響應(yīng)的主體期丰。

DestroyModelMixin

提供.destroy(request欢瞪,* args挂捻,** kwargs)方法碉纺,用于實現(xiàn)對現(xiàn)有模型實例的刪除。
如果刪除了一個對象刻撒,則返回204 No Content響應(yīng)骨田,否則返回404 Not Found。


Concrete View Classes

以下類是具體的通用視圖声怔。如果您使用的是通用視圖态贤,這通常是您將要工作的級別,除非您需要大量自定義的行為醋火。
可以從rest_framework.generics導(dǎo)入視圖類悠汽。

CreateAPIView

用于僅創(chuàng)建端點。
提供post方法處理程序芥驳。
擴展:GenericAPIView柿冲,CreateModelMixin

ListAPIView

用于只讀端點以表示模型實例的集合。
提供get方法處理程序兆旬。
擴展:GenericAPIView姻采,ListModelMixin

RetrieveAPIView

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

DestroyAPIView

用于單個模型實例的僅刪除端點婚瓜。
提供刪除方法處理程序宝鼓。
擴展: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


Customizing the generic views

通常呐伞,您會希望使用現(xiàn)有的通用視圖,但使用一些略微自定義的行為慎式。 如果您發(fā)現(xiàn)自己在多個位置重復(fù)使用某些自定義行為伶氢,則可能需要將該行為重構(gòu)為公共類,然后您可以根據(jù)需要將其應(yīng)用于任何視圖或視圖集瘪吏。

Creating custom mixins

例如癣防,如果您需要根據(jù)URL conf中的多個字段查找對象,則可以創(chuàng)建如下所示的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

然后掌眠,只要您需要應(yīng)用自定義行為蕾盯,就可以將此mixin簡單地應(yīng)用于視圖或視圖集。

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

如果您需要使用自定義行為蓝丙,則使用自定義mixins是一個不錯的選擇级遭。

Creating custom base classes

如果您在多個視圖中使用mixin,則可以更進一步渺尘,創(chuàng)建自己的一組基本視圖挫鸽,然后可以在整個項目中使用。例如:

class BaseRetrieveView(MultipleFieldLookupMixin,
                       generics.RetrieveAPIView):
    pass

class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
                                    generics.RetrieveUpdateDestroyAPIView):
    pass

如果您的自定義行為始終需要在整個項目中的大量視圖中重復(fù)鸥跟,那么使用自定義基類是一個不錯的選擇丢郊。


PUT as create

在3.0版之前盔沫,REST框架將處理后的PUT混合為更新或創(chuàng)建操作,具體取決于對象是否已存在枫匾。

允許PUT作為創(chuàng)建操作是有問題的架诞,因為它必然暴露有關(guān)對象存在或不存在的信息。 透明地允許重新創(chuàng)建先前刪除的實例也不一定比僅返回404響應(yīng)更好的默認行為干茉。

兩種樣式“PUT as 404”和“PUT as create”在不同情況下都可以有效谴忧,但從版本3.0開始,我們現(xiàn)在使用404行為作為默認值等脂,因為它更簡單俏蛮,更明顯。

如果您需要通用的PUT-as-create行為上遥,您可能希望將類似此類的AllowPUTAsCreateMixin類作為mixin包含在您的視圖中搏屑。


Third party packages

以下第三方包提供了其他通用視圖實現(xiàn)。

Django REST Framework bulk

django-rest-framework-bulk包實現(xiàn)了通用視圖mixins以及一些常見的具體通用視圖粉楚,以允許通過API請求應(yīng)用批量操作辣恋。

Django Rest Multiple Models

Django Rest Multiple Models提供了一個通用視圖(和mixin),用于通過單個API請求發(fā)送多個序列化模型和/或查詢集模软。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伟骨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子燃异,更是在濱河造成了極大的恐慌携狭,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件回俐,死亡現(xiàn)場離奇詭異逛腿,居然都是意外死亡,警方通過查閱死者的電腦和手機仅颇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門单默,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忘瓦,你說我怎么就攤上這事搁廓。” “怎么了耕皮?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵境蜕,是天一觀的道長。 經(jīng)常有香客問我凌停,道長汽摹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任苦锨,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舟舒。我一直安慰自己拉庶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布秃励。 她就那樣靜靜地躺著氏仗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夺鲜。 梳的紋絲不亂的頭發(fā)上皆尔,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音币励,去河邊找鬼慷蠕。 笑死,一個胖子當(dāng)著我的面吹牛食呻,可吹牛的內(nèi)容都是我干的流炕。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼仅胞,長吁一口氣:“原來是場噩夢啊……” “哼每辟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起干旧,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤渠欺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后椎眯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挠将,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年盅视,在試婚紗的時候發(fā)現(xiàn)自己被綠了捐名。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡闹击,死狀恐怖镶蹋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赏半,我是刑警寧澤贺归,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站断箫,受9級特大地震影響拂酣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仲义,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一婶熬、第九天 我趴在偏房一處隱蔽的房頂上張望剑勾。 院中可真熱鬧,春花似錦赵颅、人聲如沸虽另。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捂刺。三九已至,卻和暖如春募寨,著一層夾襖步出監(jiān)牢的瞬間族展,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工拔鹰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留仪缸,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓格郁,卻偏偏與公主長得像腹殿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子例书,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 《白月光》 《櫻吹雪》 《可惜不是你》 這些傷感的歌锣尉,還是少聽。白月光决采,現(xiàn)在已經(jīng)不敢再聽了 你補了這最后一刀自沧。 —...
    嵐風(fēng)的葉子閱讀 149評論 0 0
  • 我想要一個洋娃娃 I want a doll 捏著她柔軟的身體 Holding her soft body 我想要...
    吳惟閱讀 468評論 2 0
  • 買了一本考研的書。作者是網(wǎng)絡(luò)上很紅的考研講師树瞭,名叫張雪峰拇厢。這本書叫做《你離考研成功就差這本書》。名字看起來很輕浮晒喷,...
    長亭微雨閱讀 130評論 2 0