1. 程式人生 > >django之restframework使用 (二)視圖三部曲

django之restframework使用 (二)視圖三部曲

urn code sea str 通用視圖 part 配置 循環 認證

下面我來來看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",]
}

django之restframework使用 (二)視圖三部曲