下面我来来看restframework是如何将冗余的代码一步步的进行封装.
这里主要用到的是多继承
mixin类编写视图
view.py
vfrom rest_framework import mixins
from rest_framework import generics
class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers
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 AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
def get(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs)
def delete(self,request,*args, **kwargs):
return self.destroy(request,*args, **kwargs)
def put(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs)
url
url(r'^authors/$', views.AuthorModelView.as_view(),name='author')
url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view(),name="detailauthor"),
使用通用的基于类的视图
通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py
模块。
views.py
from rest_framework import generics
class AuthorView(generics.ListCreateAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers
class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
url
url(r'^authors/$', views.AuthorModelView.as_view(),name='author')
url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view(),name="detailauthor"),
到这里是第二部,但是我们还是需要实例化两个类来对应两个url,为什么要实例两个类,因为每个类都有get方法,
如果不写两个类,怎么知道走哪个get方法?
第三部viewsets.ModelViewSet
views.py:
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializers
urls.py:
url(r'^books/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name="book_list"),
url(r'^books/(?P<pk>\d+)$', views.BookViewSet.as_view({ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }),
name="book_detail"),
from rest_framework import viewsets
class AuthorModelView(viewsets.ModelViewSet):
ModelViewSet--->GenericViewSet--->ViewSetMixin----在这个类下执行了as_view
for method, action in actions.items():
#as_view后面的参数被循环后得到了请求key,相对应的方法values
handler = getattr(self, action) # handler -->getattr(self,list) self--->自己写的类AuthorModelView
setattr(self, method, handler) #setattr(self,get,self.list) self.get---->执行self.list
认证与权限组件
认证组件
局部视图认证
在app01.service.auth.py:
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)
在views.py:
def get_random_str(user):
import hashlib,time
ctime=str(time.time())
md5=hashlib.md5(bytes(user,encoding="utf8"))
md5.update(bytes(ctime,encoding="utf8"))
return md5.hexdigest()
from app01.service.auth import *
from django.http import JsonResponse
class LoginViewSet(APIView):
authentication_classes = [Authentication,]
def post(self,request,*args,**kwargs):
res={"code":1000,"msg":None}
try:
user=request._request.POST.get("user")
pwd=request._request.POST.get("pwd")
user_obj=UserInfo.objects.filter(user=user,pwd=pwd).first()
print(user,pwd,user_obj)
if not user_obj:
res["code"]=1001
res["msg"]="用户名或者密码错误"
else:
token=get_random_str(user)
UserToken.objects.update_or_create(user=user_obj,defaults={"token":token})
res["token"]=token
except Exception as e:
res["code"]=1002
res["msg"]=e
return JsonResponse(res,json_dumps_params={"ensure_ascii":False})
全局视图认证组件
settings.py配置如下:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}