【DRF-12】rest-framework之路由
-
路由控制介绍:
- 我们之前一直接触的路由是最基本的形式, 就是我们下面介绍的第一种方式的自定义路由, 无论是FBV还是CBV, 都可以使用这用方式来设置路由来设定请求来的时候对应响应视图的函数或者视图类
- 当我们使用封装了的视图类处理代码的时候, 我们就可以使用对应的半自动路由来对路由进行设置, 这时我们可以在路由中传入一个字典, 在字典中使用key:value的形式来设置请求对应的视图类中的处理方法, 具体的使用见下面的半自动路由配置
- 全自动路由配置是在路由层借助了routers来生成相应的对象来自动生成路由, 全自动路由使用的较少, 还是那句话, 本身封装的程度越高, 相应的可拓展性就越差
-
自定义路由(原始方式)
- 路由设置
from django.urls import path,re_path
from api import views
urlpatterns = [
re_path(r'^(?P<version>[v1|v2]+)/books/$', views.BookView.as_view()),
re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)$', views.BookDetailView.as_view()),
]
- 视图
from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import URLPathVersioning,QueryParameterVersioning
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = '__all__'
class BookView(APIView):
# 获取所有书籍信息
def get(self,request,*args,**kwargs):
obj = models.Book.objects.all()
ser = BookModelSerializer(instance=obj,many=True)
return Response(ser.data)
# 新增书籍信息
def post(self, request, *args, **kwargs):
ser = BookModelSerializer(data=request.data)
if ser.is_valid():
ser.save()
return HttpResponse("提交成功")
else:
return HttpResponse(ser.errors)
class BookDetailView(APIView):
# 获取单个书籍数据
def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
obj = models.Book.objects.filter(id=pk).first()
ser = BookModelSerializer(instance=obj,many=False)
return Response(ser.data)
# 删除单个书籍
def delete(self,request,*args,**kwargs):
pk = kwargs.get('pk')
models.Book.objects.filter(id=pk).delete()
return Response('删除成功')
# 更新书籍信息
def put(self,request,*args,**kwargs):
pk = kwargs.get('pk')
obj = models.Book.objects.filter(id=pk).first()
ser = BookModelSerializer(data=request.data,instance=obj)
if ser.is_valid():
ser.save()
return HttpResponse("更新成功")
else:
return Response(ser.errors)
- 半自动路由(视图类继承ModelViewSet)
- 半自动路由的使用场景是比较多的, 这里继承ModelViewSet, 实际最终还是来自于ViewSetMixin, 半自动路由正式和它配合使用的
- 半自动路由可以在路由层传入字典, 在字典中规定对应请求在是视图类中处理方法, 这样就解决了, 两个get请求需要获取不同数据的需求, 也正式这一点, 使用半自动路由的时候, 可以在视图类中可以自己自由定制对应请求在视图类中处理方法的名字, 不用再拘束于get请求要视图类中的处理方法就必须是get这样的约束.
- 路由
from django.urls import path,re_path
from api import views
urlpatterns = [
# re_path(r'^(?P<version>[v1|v2]+)/books/$', views.BookView.as_view()),
# re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)$', views.BookDetailView.as_view()),
re_path(r'^(?P<version>[v1|v2]+)/book/$', views.BookView.as_view({'get':'list','post':'create'})),
re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)/$', views.BookView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
]
- 视图
from rest_framework.viewsets import ModelViewSet
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = '__all__'
class BookView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
- 全自动路由
- 全自动路由在路由层由routers实例化出的对象辅助来完成自动化生成多个路由
- 由routers对象先注册一个基本路由, 在配置过之后就会自动生成各种围绕基本路由的路由了
- 路由
from django.conf.urls import include
from django.urls import path,re_path
from api import views
from rest_framework import routers
router = routers.DefaultRouter()
# 两个参数,一个是匹配的路由,一个是视图中写的CBV的类
router.register('book',views.BookView)
urlpatterns = [
# re_path(r'^(?P<version>[v1|v2]+)/books/$', views.BookView.as_view()),
# re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)$', views.BookDetailView.as_view()),
# re_path(r'^(?P<version>[v1|v2]+)/book/$', views.BookView.as_view({'get':'list','post':'create'})),
# re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)/$', views.BookView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
re_path(r'^(?P<version>[v1|v2]+)/', include(router.urls)),
]
- 视图
from rest_framework.viewsets import ModelViewSet
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = '__all__'
class BookView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
- 我们输入错误的路由,可以看到book生成了对应的4个路由