django restframework框架八 路由
@(python之路)[django restframework框架八 路由]
django restframework框架八 路由
目录
路由组件
一般路由我们会写六个方法:
- 列表:SaView.get
- 添加:SaView.post
- 详细:SaView.get
- 修改:SaView.put
- 局部:SaView.patch
- 删除:SaView.delete
一般的路由都是有这六部分组成
路由组件编写
a. 自定义路由
urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'sa/$', views.SaView.as_view()),
url(r'sa/(?(pk)\d+)/$', views.SaView.as_view()),
]
views.py
class SaSerialiser(serializers.ModelSerializer):
class Meta:
model = models.Sa
fields = "__all__"
class SaView(APIView):
authentication_classes = []
def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if not pk:
queryset = models.Sa.objects.all()
ser = SaSerialiser(instance=queryset,many=True)
else:
obj = models.Sa.objects.filter(id=pk).first()
ser = SaSerialiser(instance=obj, many=False)
return Response(ser.data)
def post(self,request,*args,**kwargs):
pass
def put(self,request,*args,**kwargs):
kwargs.get('pk')
pass
def patch(self,request,*args,**kwargs):
kwargs.get('pk')
pass
def delete(self,request,*args,**kwargs):
kwargs.get('pk')
pass
弊端:视图函数做修改,这里也需要做修改
b. 半自动路由
urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'sa/$', views.SaView.as_view({'get': 'list', 'post': 'create'})),
url(r'sa/(?(pk)\d+)/$', views.SaView.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),
]
此时我们的views就要换一种方式了
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers
from .. import models
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__"
class UserViewSet(ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = UserSerializer
c. 全自动路由
urls.py
from django.conf.urls import url, include
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'sa', views.SaView)
urlpatterns = [
url(r'^', include(router.urls)),
]
views.py
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers
from .. import models
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__"
class UserViewSet(ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = UserSerializer
不推荐这种方式
源码分析
1
from rest_framework.viewsets import GenericViewSet
class SaView(APIView):
pass
我们来看一下GenericViewSet
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
pass
这里GenericViewSet
继承了ViewSetMixin
和generics.GenericAPIView
这里我们先看一下generics.GenericAPIView
class GenericAPIView(views.APIView):
queryset = None
serializer_class = None
lookup_field = 'pk'
lookup_url_kwarg = None
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get_queryset(self):
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
# 这里的本质就是 self.queryset= queryset = None;
# 这里单纯的它是没有意义的。我们需要结合其他的来用。他是用来调用增删改查的。稍后会仔细说。
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset
我们现在来看,GenericAPIView
并没有起到什么作用。所以我们继续看ViewSetMixin
。
class ViewSetMixin(object):
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
pass
我们关注的是as_view()
他这里需要重新写了as_view方法。所以我们的路由也要跟着改变。语言来的变化请看b
2
ModelViewSet
:代码示例请看c
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass
我们发现他继承了五个类,