類的繼承: 繼承了原生View類並繼承了as_view方法django
api
pip install djangorestframework #下載djangorestframeworkapp
from rest_framework.views import APIView
class LoginView(APIView):
def get(self, request):
pass
class LoginView(APIView):
def get(self, request):
pass
def post(self, request):
request.data # 新的request對象 @property
return
class APIView(View):
views.LoginView.as_view()ide
LoginView裏面沒有as_view方法,到父類APIView去找函數
執行View裏面的as_view()方法,返回view函數 def view(request, *args, kwargs): self = cls(initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs)post
url和視圖函數之間的綁定關係創建完畢 { "login": view},等待用戶請求優化
接收到用戶請求:login,到創建好的綁定關係裏面執行對應的視圖函數:view(request)ui
視圖函數的執行結果是什麼就返回給用戶什麼:self.dispatch(), self.dispatch()的執行結果是什麼,就返回給用戶什麼url
此時的self表明的是LoginView的實例化對象spa
開始找dispatch方法,self裏面沒有,LoginView裏面也沒有,在APIView裏面有
開始執行APIView裏面的dispatch
最後找到http方法(GET,POST,PUT,DELETE),根據請求類型查找(request.method.lower())
開始執行找到的方法(GET),self.get(), self此時表明LoginView的實例化對象 11.1 假設接收到的是POST請求, 執行request.data 11.2 根據分析,全部的解析工做都在request.data裏面實現,且data是一個方法(被裝飾後的) 11.2 開始執行request.data @property def data(self): if not hasattr(self, 'full_data'): self.load_data_and_files() return self.full_data 11.3 執行self.load_data_and_files 11.4 執行self.data, self.files = self.parse() 11.5 parser = self.negotiator.select_parser(self, self.parsers) 11.5.1 開始找self.parsers 11.5.2 self.get_parses() [ parse() for parse in self.parser_classes ] 11.5.3 parser_classes = api_settings.DEFAULT_PARSER_CLASSES 11.5.4 from rest_framework import api_settings 11.5.5 api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS) 11.5.6 class APISettings():pass
11.5.7 找不到DEFAULT_PARSER_CLASSES,getattr 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ),
11.5.8 首先找程序的settings
11.5.9 而後找rest_framework的settings
11.6 self.data就是咱們想要的數據 11.7 DRF將self.data = data 11.8 request.data
在LoginView裏面找到了對應的方法,執行該方法,最後返回給用戶
DRF的全部功能都是在as_view()和dispatch裏面重寫的
而解析器組件在dispatch方法裏面重寫了,具體是在從新封裝的Request對象裏面
GET 127.0.0.1:8000/books/ # 獲取全部數據,返回值: [{}, {}]
GET 127.0.0.1:8000/books/{id} # 獲取一條數據,返回值:{}
POST 127.0.0.1:8000/books/ # 新增一條數據,返回值:{}
PUT 127.0.0.1:8000/books/{id} # 修改數據,返回值:{}
DELETE 127.0.0.1:8000/books/{id} # 刪除數據,返回空
導入模塊:from rest_framework import serializers
創建一個序列化類:
class BookSerializer(serializers.Serializer):
publish_name = serializers.CharField(read_only=True, source="publish.name")
authors_list = serializers.SerializerMethodField()
def get_authors_list(self, book_obj):
pass
開始序列化:
class BookView(APIView):
def get(self, request):
origin_data = Book.objects.all() #獲取queryset
serialized_data = BookSerializer(origin_data, many=True) #開始序列化
#book_obj = Book.objects.all()
#serialized_data = BookSerializer(book_obj, many=False) get單條數據接口設計
return Response(serialized_data.data) #獲取序列化後的數據,返回給客戶端
def post(self, request):
verified_data = BookSerializer(data=request.data)
if verified_data.is_valid():
book = verified_data.save()
authors=Author.objects.filter(nid__in=request.data
['authors'])
book.authors.add(*authors)
return Response(verified_data.data)
else:
return Response(verified_data.errors)
def put(self, request, nid):
book_obj = Book.objects.get(pk=nid)
verified_data = BookSerializer(data=request.data, instance=book_obj)
if verified_data.is_valid():
verified_data.save()
return Response(verified_data.data)
else:
return Response(verified_data.errors)
from rest_framework.mixinx import (
ListModelMix,
CreateModelMixin,
DestroyModelMixin,
UpdateModelMixin,
RetrieveModelMixin
)
from rest_framework.generics import GenericAPIView
class BookSerializer(serializers.ModelSerializer):
class Meata:
model = Book
fields = ('field_name', )
extra_kwargs = {"publish": {"write_only": True}, }
publish_name = serializers.CharField(read_only=True, source="publish.name")
authors = serializers.SerializerMethodField()
def get_authors(self, book_obj):
pass
from .app_serializers import BookSerializer
class BookView(ListModelMix, CreateModelMixin, GenericAPIView):
#queryset和serializer_class是固定的寫法
queryset = Book.objects.all()
serializer_class = BookSerializer
def get():
return self.list()
def post():
return self.create()
class BookFilterView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get():
return self.retrieve()
def delete():
return self.destroy()
def put():
return self.update()
#注意:單條數據操做的url是這樣的:re_path(r'books/(?P<pk>\d+)/$, views.BookFilterView.as_view())
from rest_framework import generics
class BookView(generics.ListCreateAPIView)
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
from rest_framework.viewsets import ModelViewSet
re_path(r'books/$', views.BookView.as_view({
'get': 'list',
'post': 'create'
})),
re_path(r'books/(?P<pk>\d+)/$', views.BookView.as_view({
'get': 'retrieve',
'delete': 'destroy',
'put': 'update'
}))
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
class UserAuth():
def authenticate_header(self, request):
pass
def authenticate(self, request):
pass
class BookView(ModelViewSet):
authentication_classes = [UserAuth]
queryset = Book.objects.all()
serializer_class = BookSerializer
在settings文件裏面指定:
REST_FRAMEWORK = {
"DEFAULT_PARSER_CLASSES": (JsonParser, FormParser),
"DEFAULT_AUTHENTICATION_CLASSES": ("serializer.utils.app_authes.UserAuth",)
}
- self.dispatch() # self BookView的實例化對象
- self.initial() # self BookView的實例化對象
- self.perform_authentication() # self BookView的實例化對象
- request.user # self Request的實例化對象
- self._authenticate() # self Request的實例化對象
self.user = xxx
class UserPerm():
def has_permission(self, request, view):
if 有權限:
return True
else:
return False
class BookView(APIView):
permission_classes = [UserPerm]
class RateThrottle():
def allow_request(request, self):
if 沒有超過限制:
return True
else:
return False
def wait(self):
return 10
class BookView(APIView):
throttle_classes = [RateThrottle]
-導入模塊
from rest_framework.throttling import SimpleRateThrottle
- 定義並繼承SimpleRateThrottle
class RateThrottle(SimpleRateThrottle):
# 指定訪問頻率
rate = '5/m'
# 指定經過什麼方式來區分用戶
def get_cache_key(self, request, view):
return self.get_ident(request)
- 指定頻率類
class BookView(APIView):
throttle_classes = [RateThrottle]
-導入模塊
from rest_framework.throttling import SimpleRateThrottle
- 定義並繼承SimpleRateThrottle
class RateThrottle(SimpleRateThrottle):
# 指定訪問頻率
scope = 'visit_rate'
# 指定經過什麼方式來區分用戶
def get_cache_key(self, request, view):
return self.get_ident(request)
- 在settings裏面指定頻率類和訪問頻率
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES": ('serializer.utils.app_throttles.RateThrottle',),
"DEFAULT_THROTTLE_RATES": {
"visit_rate": "5/m"
}
}
from django.urls import re_path, include
from .serializer import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r"books", views.BookView)
urlpatterns = [
re_path('^', include(router.urls)),
]
- 導入模塊
from rest_framework.pagination import PageNumberPagination
- 獲取數據
books = Book.objects.all()
- 建立一個分頁器對象
paginater = PageNumberPagination()
- 開始分頁
paged_books = paginater.paginate_queryset(books, request)
- 開始序列化
serialized_books = BookSerializer(paged_books, many=True)
- 返回數據
return Response(serialized_books.data)
- 導入模塊
from rest_framework.pagination import PageNumberPagination
- 自定義一個分頁類並集成PageNumberPagination
class MyPagination(PageNumberPagination):
page_size = 2
page_query_param = 'p'
page_size_query_param = 'size'
max_page_size = 5
- 實例化一個分頁類對象
paginater = MyPagination()
- 開始分頁
paged_books = paginater.paginate_queryset(books, request)
- 開始序列化
serialized_books = BookSerializer(paged_books, many=True)
- 返回數據
return Response(serialized_books.data)
from rest_framework.renderers import JsonRender
class BookView(APIView):
render_classes = [JsonRender]