- 視圖類傳遞參數給序列化類
- 二次封裝Response
- 視圖家族簡介
- generics APIView視圖基類
- mixins視圖六大工具類
- generic中的工具視圖
- 視圖集viewsets
- ModelViewSet擁有六大接口
- 總結
- 路由元件(了解)
-曾老濕, 江湖人稱曾老大。
-多年網際網路運維工作經驗,曾負責過大規模叢集架構自動化運維管理工作。
-擅長Web叢集架構與自動化運維,曾負責國内某大型金融公司運維工作。
-devops項目經理兼DBA。
-開發過一套自動化運維平台(功能如下):
1)整合了各個公有雲API,自主建立雲主機。
2)ELK自動化收集日志功能。
3)Saltstack自動化運維統一配置管理工具。
4)Git、Jenkins自動化代碼上線及自動化測試平台。
5)堡壘機,連接配接Linux、Windows平台及日志審計。
6)SQL執行及審批流程。
7)慢查詢日志分析web界面。
視圖類傳遞參數給序列化類
介紹 |
---|
# 1)在視圖類中執行個體化序列化對象時,可以設定context内容
# 2)在序列化類中的局部鈎子、全局鈎子、create、update方法中,都可以用self.context通路視圖類傳遞過來的内容
# 需求:
# 1) 在視圖類中,可以通過request得到登陸使用者request.user
# 2) 在序列化類中,要完成資料庫資料的校驗與入庫操作,可能會需要知道目前的登陸使用者,但序列化類無法通路request
# 3) 在視圖類中執行個體化序列化對象時,将request對象傳遞進去
複制
視圖層 |
---|
class Book(APIView):
def post(self, request, *args, **kwargs):
book_ser = serializers.BookModelSerializer(data=request_data,context={'request':request})
book_ser.is_valid(raise_exception=True)
book_result = book_ser.save()
return Response({
'status': 0,
'msg': 'ok',
'results': serializers.BookModelSerializer(book_result).data
})
複制
序列化層 |
---|
class BookModelSerializer(ModelSerializer):
class Meta:
model = models.Book
fields = ('name', 'price')
def validate_name(self, value):
print(self.context.get('request').method)
return value
複制
二次封裝Response
我們之前在寫視圖的時候,發現寫了大量的Response資訊,反複寫,反複寫,重複代碼,如下:
return Response({
'status': 1,
'msg': '資料有誤'
})
return Response({
'status': 0,
'msg': 'put OK',
'results': serializers.V2BookModelSerializer(book_obj).data
})
複制
封裝 |
---|
我們在項目目錄下新建立一個目錄:utils
然後再utils中建立response.py檔案

from rest_framework.response import Response
"""
Response({
'status':0,
'msg':'ok',
'results':[],
'token':'', # 有 這樣的額外的key-value資料結果
},status=http_status,headers=headers,exceptio=True|False)
## 我們想要的結果,就是在APIResponse上加上括号就出來最簡單的結果
APIResponse() => Respone({'status':0, 'msg':'ok',})
"""
class APIResponse(Response):
def __init__(self, data_status=0, data_msg='ok', results=None, http_status=None, headers=None, exception=False,
**kwargs):
data = {
'status': data_status,
'msg': data_msg
}
## results可能是False、0等資料,這些資料某些情況下,也會作為合法資料傳回
if results is not None:
data['results'] = results
if kwargs is not None:
for k, v in kwargs.items():
setattr(data, k, v) ## 反射,相當于:data[k] = v
super().__init__(data=data, status=http_status, headers=headers, exception=exception)
複制
測試 |
---|
from rest_framework.views import APIView
from rest_framework.response import Response
from . import models, serializers
## 導入
from utils.response import APIResponse
class V2Book(APIView):
# 單查:有pk
# 群查:無pk
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
try:
book_obj = models.Book.objects.get(pk=pk, is_delete=False)
book_data = serializers.V2BookModelSerializer(book_obj).data
except:
return Response({
'status': 1,
'msg': '書籍不存在'
})
else:
book_query = models.Book.objects.filter(is_delete=False).all()
book_data = serializers.V2BookModelSerializer(book_query, many=True).data
return Response({
'status': 0,
'msg': 'ok',
'results': book_data
})
# 單增:傳的資料是與model對應的字典
# 群增:傳的資料是 裝多個 model對應字典 的清單
def post(self, request, *args, **kwargs):
request_data = request.data
if isinstance(request_data, dict):
many = False
elif isinstance(request_data, list):
many = True
else:
return Response({
'status': 1,
'msg': '資料有誤',
})
book_ser = serializers.V2BookModelSerializer(data=request_data, many=many)
# 當校驗失敗,馬上終止目前視圖方法,抛異常傳回給前台
book_ser.is_valid(raise_exception=True)
book_result = book_ser.save()
return Response({
'status': 0,
'msg': 'ok',
'results': serializers.V2BookModelSerializer(book_result, many=many).data
})
# 單删:有pk
# 群删:有pks | {"pks": [1, 2, 3]}
def delete(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
pks = [pk]
else:
pks = request.data.get('pks')
if models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True):
return Response({
'status': 0,
'msg': '删除成功',
})
return Response({
'status': 1,
'msg': '删除失敗',
})
# 單整體改,傳的資料是與model對應的字典{name|price|publish|authors}
def put(self, request, *args, **kwargs):
request_data = request.data
pk = kwargs.get('pk')
old_book_obj = models.Book.objects.filter(pk=pk).first()
## 将衆多 資料的校驗交給序列化類來 處理,讓序列化累扮演反序列化的角色,校驗成功後,序列化幫你入庫
book_ser = serializers.V2BookModelSerializer(instance=old_book_obj, data=request_data)
book_ser.is_valid(raise_exception=True)
# 校驗通過,完成資料的更新:要知道更新的目标,用來更新的新資料
book_obj = book_ser.save()
return Response({
'status': 0,
'msg': 'put OK',
'results': serializers.V2BookModelSerializer(book_obj).data
})
# 單局部改
def patch(self, request, *args, **kwargs):
request_data = request.data
pk = kwargs.get('pk')
## 将單改群改的資料都格式化成pks=[需要修改的對象主鍵辨別] | request_data = [每個要修改對象對應的的修改資料]
if pk and isinstance(request_data, dict): # 單改
pks = [pk, ]
request_data = [request_data, ]
elif not pk and isinstance(request_data, list): # 群改
pks = []
for dic in request_data:
pk = dic.pop('pk', None)
if pk:
pks.append(pk)
else:
return Response({
'status': 1,
'msg': '資料有誤'
})
else:
return Response({
'status': 1,
'msg': '資料有誤'
})
# 将不能操作的資料 剔除 pks與request_data資料篩選
objs = []
new_request_data = []
for index, pk in enumerate(pks):
try:
## pk對應的資料合理,将合理的對象存儲
obj = models.Book.objects.get(pk=pk, is_delete=False)
objs.append(obj)
new_request_data.append(request_data[index])
except:
# pk對應的資料有誤,将對應索引的data中request_data中移除
# index = pks.index(pk)
# request_data.pop(index)
continue
book_ser = serializers.V2BookModelSerializer(instance=objs, data=new_request_data, partial=True, many=True)
book_ser.is_valid(raise_exception=True)
# 校驗通過,完成資料的更新:要知道更新的目标,用來更新的新資料
book_objs = book_ser.save()
book_objs_data = serializers.V2BookModelSerializer(book_objs, many=True).data
return APIResponse(results=book_objs_data)
複制

視圖家族簡介
介紹 |
---|
"""
views:視圖
generics:工具視圖
mixins:視圖工具集
viewsets:視圖集
"""
"""
學習曲線
APIView => GenericAPIView => mixins的五大工具類 => generics中的工具視圖 => viewsets中的視圖集
"""
複制
generics APIView視圖基類
先把之前序列化的東西儲存下來,然後清空views檔案,我們要開始學習視圖了。

路由 |
---|
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v1/books/$', views.BookAPIView.as_view()),
url(r'^v1/books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
]
複制
序列化 |
---|
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.exceptions import ValidationError
from . import models
from rest_framework.serializers import ListSerializer
class BookListSerializer(ListSerializer):
def update(self, instance, validated_data):
for index, obj in enumerate(instance):
self.child.update(obj, validated_data[index])
return instance
class BookModelSerializer(ModelSerializer):
class Meta:
model = models.Book
fields = ('name', 'price', 'img', 'author_list', 'publish_name', 'publish', 'authors')
extra_kwargs = {
'name': {
'required': True,
'min_length': 1,
'error_messages': {
'required': '必填項',
'min_length': '太短',
}
},
'publish': {
'write_only': True
},
'authors': {
'write_only': True
},
'img': {
'read_only': True,
},
'author_list': {
'read_only': True,
},
'publish_name': {
'read_only': True,
}
}
list_serializer_class = BookListSerializer
def validate_name(self, value):
if 'g' in value.lower():
raise ValidationError('該g書不能出版')
return value
def validate(self, attrs):
publish = attrs.get('publish')
name = attrs.get('name')
if models.Book.objects.filter(name=name, publish=publish):
raise ValidationError({'book': '該書已存在'})
return attrs
複制
APIView視圖 |
---|
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
class BookAPIView(APIView):
def get(self, request, *args, **kwargs):
book_query = models.Book.objects.filter(is_delete=False).all()
book_ser = serializers.BookModelSerializer(book_query, many=True)
book_data = book_ser.data
return APIResponse(results=book_data)
複制

GenericAPIView視圖 |
---|
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
## GenericAPIView 是繼承APIView的 ,完全相容APIView
from rest_framework.generics import GenericAPIView
class BookGenericAPIView(GenericAPIView):
def get(self, request, *args, **kwargs):
book_query = models.Book.objects.filter(is_delete=False).all()
book_ser = serializers.BookModelSerializer(book_query, many=True)
book_data = book_ser.data
return APIResponse(results=book_data)
複制

代碼沒有改變,結果完全一樣。
GenericAPIView視圖對比APIView |
---|
重點:GenericAPIView在APIView的基礎上完成了哪些事?
1.get_queryset()
2.get_object()
3.get_serializer()
修改代碼如下:
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
## GenericAPIView 是繼承APIView的 ,完全相容APIView
from rest_framework.generics import GenericAPIView
### 群取
class BookGenericAPIView(GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False).all()
serializer_class = serializers.BookModelSerializer
def get(self, request, *args, **kwargs):
book_query = self.get_queryset()
book_ser = self.get_serializer(book_query, many=True)
book_data = book_ser.data
return APIResponse(results=book_data)
複制
我擦,本來的4步,變成了6步。
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
## GenericAPIView 是繼承APIView的 ,完全相容APIView
from rest_framework.generics import GenericAPIView
class BookGenericAPIView(GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False).all()
serializer_class = serializers.BookModelSerializer
## 單取
def get(self, request, *args, **kwargs):
book_query = self.get_object()
book_ser = self.get_serializer(book_query)
book_data = book_ser.data
return APIResponse(results=book_data)
複制

單取的路由,有名分組,必須叫pk,否則就會報錯
<api.views.BookGenericAPIView object at 0x112135470> - GET - Expected view BookGenericAPIView to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.
複制
總結:
1.get_queryset():從類屬性queryset中獲得model的queryset資料
2.get_object():從類屬性queryset中獲得model的queryset資料,再通過有名分組pk确定唯一操作對象
當然也可以自定義主鍵的有名分組名稱
lookup_field = 'id'
3.get_serializer():從類屬性serializer_class中獲得serializer的序列化類
單取,群取合并 |
---|
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
class BookAPIView(APIView):
def get(self, request, *args, **kwargs):
book_query = models.Book.objects.filter(is_delete=False).all()
book_ser = serializers.BookModelSerializer(book_query, many=True)
book_data = book_ser.data
return APIResponse(results=book_data)
## GenericAPIView 是繼承APIView的 ,完全相容APIView
from rest_framework.generics import GenericAPIView
class BookGenericAPIView(GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False).all()
serializer_class = serializers.BookModelSerializer
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
return self.list(self, request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return self.retrieve(self, request, *args, **kwargs)
def list(self, request, *args, **kwargs):
book_query = self.get_queryset()
book_ser = self.get_serializer(book_query,many=True)
book_data = book_ser.data
return APIResponse(results=book_data)
def retrieve(self, request, *args, **kwargs):
book_query = self.get_object()
book_ser = self.get_serializer(book_query)
book_data = book_ser.data
return APIResponse(results=book_data)
複制
上面的代碼能看懂,就看,看不懂也不要緊...不要'緊'的,為啥呢?因為别人幫我們幹了...
mixins視圖六大工具類
路由 |
---|
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v1/books/$', views.BookAPIView.as_view()),
url(r'^v1/books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
url(r'^v3/books/$', views.BookListGenericAPIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$', views.BookListGenericAPIView.as_view()),
]
複制
視圖 |
---|
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin
class BookListGenericAPIView(ListModelMixin, GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
## 群查
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
複制

使用自定義的APIresponse |
---|
class BookListGenericAPIView(ListModelMixin, GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
## 群查
def get(self, request, *args, **kwargs):
response = self.list(request, *args, **kwargs)
return APIResponse(results=response.data)
複制

實作增加方法 |
---|
修改一下路由名稱
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v1/books/$', views.BookAPIView.as_view()),
url(r'^v1/books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
url(r'^v3/books/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
]
複制
修改方法名,添加增加方法
class BookMixinGenericAPIView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
## 群查
def get(self, request, *args, **kwargs):
response = self.list(request, *args, **kwargs)
return APIResponse(results=response.data)
def post(self, request, *args, **kwargs):
response = self.create(request, *args, **kwargs)
return APIResponse(results=response.data)
複制

單查群查放一起 |
---|
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin
class BookMixinGenericAPIView(ListModelMixin, CreateModelMixin, RetrieveModelMixin, GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
## 群查
def get(self, request, *args, **kwargs):
if 'pk' in kwargs:
response = self.retrieve(request, *args, **kwargs)
else:
response = self.list(request, *args, **kwargs)
return APIResponse(results=response.data)
def post(self, request, *args, **kwargs):
response = self.create(request, *args, **kwargs)
return APIResponse(results=response.data)
複制


單改,群改 |
---|
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
class BookMixinGenericAPIView(ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
## 查詢
def get(self, request, *args, **kwargs):
if 'pk' in kwargs:
## 單查
response = self.retrieve(request, *args, **kwargs)
else:
## 群查
response = self.list(request, *args, **kwargs)
return APIResponse(results=response.data)
## 增加
def post(self, request, *args, **kwargs):
## 單增
response = self.create(request, *args, **kwargs)
return APIResponse(results=response.data)
## 修改
def put(self, request, *args, **kwargs):
## 單改
response = self.update(request, *args, **kwargs)
return APIResponse(results=response.data)
## 群改
def patch(self, request, *args, **kwargs):
response = self.partial_update(request, *args, **kwargs)
return APIResponse(results=response.data)
複制
generic中的工具視圖
我們學了 Generic 視圖
然後學了 Mixins 工具
接下來學習内容是drf中Generic結合了Mixins,工具視圖
群查單增,路由 |
---|
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v1/books/$', views.BookAPIView.as_view()),
url(r'^v1/books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
url(r'^v3/books/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v4/books/$', views.BookListCreateAPIView.as_view()),
url(r'^v4/books/(?P<pk>.*)/$', views.BookListCreateAPIView.as_view()),
]
複制
群查單增,視圖 |
---|
from rest_framework.generics import ListCreateAPIView
class BookListCreateAPIView(ListCreateAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
複制
四句話,完成群查和單增...


如果想要加上修改方法,不需要單獨寫,同樣繼承一下即可,還是4句話
from rest_framework.generics import ListCreateAPIView, UpdateAPIView
class BookListCreateAPIView(ListCreateAPIView, UpdateAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
複制


視圖集viewsets
重寫了 as_view
視圖 |
---|
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
from rest_framework.generics import GenericAPIView
from rest_framework.generics import ListCreateAPIView, UpdateAPIView
class BookListCreateAPIView(ListCreateAPIView, UpdateAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
from rest_framework.viewsets import GenericViewSet
class BookGenericViewSet(GenericViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
## 假裝是群查
def my_get_list(self, request, *args, **kwargs):
return APIResponse(0,'假裝這是群查,走到這肯定是成功了')
## 假裝是單查
def my_get_obj(self, request, *args, **kwargs):
return APIResponse(0, '假裝這是單查,走到這肯定是成功了')
複制
路由 |
---|
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v1/books/$', views.BookAPIView.as_view()),
url(r'^v1/books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
url(r'^v3/books/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v4/books/$', views.BookListCreateAPIView.as_view()),
url(r'^v4/books/(?P<pk>.*)/$', views.BookListCreateAPIView.as_view()),
url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
url(r'^v5/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({'get': 'my_get_obj'})),
]
複制


完善單查和群查 |
---|
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, GenericViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
## 真·群查
def my_get_list(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
## 真·單查
def my_get_obj(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
複制
ModelViewSet擁有六大接口
路由 |
---|
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v1/books/$', views.BookAPIView.as_view()),
url(r'^v1/books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
url(r'^v3/books/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v4/books/$', views.BookListCreateAPIView.as_view()),
url(r'^v4/books/(?P<pk>.*)/$', views.BookListCreateAPIView.as_view()),
url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
url(r'^v5/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({'get': 'my_get_obj'})),
url(r'^v6/books/$', views.BookModelViewSet.as_view({'get': 'list', 'post': 'create'})),
url(r'^v6/books/(?P<pk>.*)/$',views.BookModelViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update'})),
]
複制
視圖 |
---|
就下面幾句話,六大接口搞定了...但是删除,一定要重寫,否則會删除資料庫
from rest_framework.viewsets import ModelViewSet
class BookModelViewSet(ModelViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
複制
1.群查

2.單查

3.單增

4.單改

重寫删除 |
---|
視圖
from rest_framework.viewsets import ModelViewSet
class BookModelViewSet(ModelViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
if not instance:
return APIResponse(1, '删除失敗')
instance.is_delete = True
instance.save()
return APIResponse(0, '删除成功')
複制
路由
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v1/books/$', views.BookAPIView.as_view()),
url(r'^v1/books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
url(r'^v3/books/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
url(r'^v4/books/$', views.BookListCreateAPIView.as_view()),
url(r'^v4/books/(?P<pk>.*)/$', views.BookListCreateAPIView.as_view()),
url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
url(r'^v5/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({'get': 'my_get_obj'})),
url(r'^v6/books/$', views.BookModelViewSet.as_view({'get': 'list', 'post': 'create'})),
url(r'^v6/books/(?P<pk>.*)/$',
views.BookModelViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update','delete':'destroy'})),
]
複制

總結
GenericAPIView視圖集
# GenericAPIView是繼承APIView的,使用完全相容APIView
# 重點:GenericAPIView在APIView基礎上完成了哪些事
# 1)get_queryset():從類屬性queryset中獲得model的queryset資料
# 2)get_object():從類屬性queryset中獲得model的queryset資料,再通過有名分組pk确定唯一操作對象
# 3)get_serializer():從類屬性serializer_class中獲得serializer的序列化類
複制
mixins工具集
# 1)mixins有五個工具類檔案,一共提供了五個工具類,六個工具方法:單查、群查、單增、單删、單整體改、單局部改
# 2)繼承工具類可以簡化請求函數的實作體,但是必須繼承GenericAPIView,需要GenericAPIView類提供的幾個類屬性和方法(見上方GenericAPIView基類知識點)
# 3)工具類的工具方法傳回值都是Response類型對象,如果要格式化資料格式再傳回給前台,可以通過 response.data 拿到工具方法傳回的Response類型對象的響應資料
複制
工具視圖
# 1)工具視圖都是GenericAPIView的子類,且不同的子類繼承了不聽的工具類,重寫了請求方法
# 2)工具視圖的功能如果直接可以滿足需求,隻需要繼承工具視圖,提供queryset與serializer_class即可
複制
視圖集
# 1)視圖集都是優先繼承ViewSetMixin類,再繼承一個視圖類(GenericAPIView或APIView)
# GenericViewSet、ViewSet
# 2)ViewSetMixin提供了重寫的as_view()方法,繼承視圖集的視圖類,配置路由時調用as_view()必須傳入 請求名-函數名 映射關系字典
# eg: url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
# 表示get請求會交給my_get_list視圖函數處理
複制
GenericAPIView 與 APIView 作為兩大繼承視圖的差別
# 1)GenericViewSet和ViewSet都繼承了ViewSetMixin,as_view都可以配置 請求-函數 映射
# 2)GenericViewSet繼承的是GenericAPIView視圖類,用來完成标準的 model 類操作接口
# 3)ViewSet繼承的是APIView視圖類,用來完成不需要 model 類參與,或是非标準的 model 類操作接口
# post請求在标準的 model 類操作下就是新增接口,登陸的post不滿足
# post請求驗證碼的接口,不需要 model 類的參與
# 案例:登陸的post請求,并不是完成資料的新增,隻是用post送出資料,得到的結果也不是登陸的使用者資訊,而是登陸的認證資訊
複制
路由元件(了解)
from django.conf.urls import include
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
# 所有路由與ViewSet視圖類的都可以注冊,會産生 '^v6/books/$' 和 '^v6/books/(?P<pk>[^/.]+)/$'
router.register('v6/books', views.BookModelViewSet)
urlpatterns = [
# 第一種添加子清單方式
url(r'^', include(router.urls)),
]
# 第二種添加子清單方式
# urlpatterns.extend(router.urls)
複制