1. CBV
FBV: url("index/",index) # index(request) url("index/(\d+)",index) # index(request,5) url("index/(?P\d\d+)",index)# index(request,name=bender) def index(request):pass CBV: url("index/",IndexView.as_view()) from django.views import View class IndexView(View): def get(self,request): pass def post(self,request): pass
2. APIView
from rest_framework.views import APIViewclass APIView(View): def as_view(): view = super(APIView, cls).as_view(**initkwargs) # self.dispatch def dispatch(): # 重新封装request request = self.initialize_request(request, *args, **kwargs) self.request = request # 初始化操作 self.initial(request, *args, **kwargs) if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(),self.http_method_not_allowed) response = handler(request, *args, **kwargs) # self.get(request, *args, **kwargs)
3. 序列化组件
class BookViewSet(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializers
from rest_framework import serializersclass PublishSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = '__all__'
4. 视图
方法一:最原始的方法
from rest_framework import serializersclass BookSerializers(serializers.ModelSerializer): class Meta: model=Book fields="__all__"class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() bs=BookSerializers(book_list,many=True,context={'request': request}) return Response(bs.data) def post(self,request,*args,**kwargs): print(request.data) bs=BookSerializers(data=request.data,many=False) if bs.is_valid(): print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)class BookDetailViewSet(APIView): def get(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,context={'request': request}) return Response(bs.data) def put(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,data=request.data,context={'request': request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
方法二:mixin类编写视图
from rest_framework import mixinsfrom rest_framework import genericsclass BookViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs)class BookDetailViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
方法三:使用通用的基于类的视图
from rest_framework import mixinsfrom rest_framework import genericsclass BookViewSet(generics.ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerializersclass BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerializers
终极方法:viewsets.ModelViewSet
url(r'^books/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name="book_list"),url(r'^books/(?P\d+)$', views.BookViewSet.as_view({ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}), name="book_detail"),视图部分:class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializers
5. 认证组件
class Authentication(BaseAuthentication): def authenticate(self,request): token=request._request.GET.get("token") token_obj=UserToken.objects.filter(token=token).first() if not token_obj: raise exceptions.AuthenticationFailed("验证失败!") return (token_obj.user,token_obj)
6. 权限组件
from rest_framework.permissions import BasePermissionclass SVIPPermission(BasePermission): message="SVIP才能访问!" def has_permission(self, request, view): if request.user.user_type==3: return True return False
7. 频率组件
from rest_framework.throttling import BaseThrottle, SimpleRateThrottleimport timeVISITED_RECORD = {}class VisitThrottle(BaseThrottle): def __init__(self): self.history = None def allow_request(self, request, view): print(self.get_ident(request)) visit_ip = self.get_ident(request) ctime = time.time() # 第一次访问 if visit_ip not in VISITED_RECORD: VISITED_RECORD[visit_ip] = [ctime] return True self.history = VISITED_RECORD[visit_ip] # 当前请求IP的记录列表 # 第二/三次访问 if len(VISITED_RECORD[visit_ip]) < 3: VISITED_RECORD[visit_ip].insert(0, ctime) return True if ctime - VISITED_RECORD[visit_ip][-1] > 60: VISITED_RECORD[visit_ip].pop() VISITED_RECORD[visit_ip].insert(0, ctime) print("ok") return True return False def wait(self): import time ctime = time.time() return 60 - (ctime - self.history[-1])class VisitThrottles(SimpleRateThrottle): scope = "xxx" def get_cache_key(self, request, view): return self.get_ident(request)
8. 解析器
from rest_framework.parsers import JSONParser,FormParserclass PublishViewSet(generics.ListCreateAPIView): parser_classes = [FormParser,JSONParser] queryset = Publish.objects.all() serializer_class = PublshSerializers def post(self, request, *args, **kwargs): print("request.data",request.data)
9. 分页
from rest_framework.pagination import PageNumberPagination,LimitOffsetPaginationclass PNPagination(PageNumberPagination): page_size = 1 page_query_param = 'page' page_size_query_param = "size" max_page_size = 5class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializers def list(self,request,*args,**kwargs): book_list=Book.objects.all() pp=LimitOffsetPagination() pager_books=pp.paginate_queryset(queryset=book_list,request=request,view=self) print(pager_books) bs=BookSerializers(pager_books,many=True) #return Response(bs.data) return pp.get_paginated_response(bs.data)
10. 路由
from django.conf.urls import url, includefrom snippets import viewsfrom rest_framework.routers import DefaultRouter# 创建路由器并注册我们的视图。router = DefaultRouter()router.register(r'snippets', views.SnippetViewSet)router.register(r'users', views.UserViewSet)# API URL现在由路由器自动确定。# 另外,我们还要包含可浏览的API的登录URL。urlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))]
11. 响应器
from rest_framework.renderers import BrowsableAPIRenderer, JSONRenderer # 响应器组件