drf 自动生成路由

drf路由系统

由于继承了ViewSetMinxin类 路由的写法变了,有三种写法。需要学习一下

  1. 原生写法
path('books/',views.BookView.as_view())
  1. 继承ViewSetMinxin重写as_view后的写法
path('books/',views.BookView.as_view({'get':'list','post':'create'}))
  1. 自动生成路由

drf 提供了两个路由类,继承ModelViewSet后路由可以自动生成。

SimpleRouter与DefaultRouter

# 1. 导入路由类
from rest_framework.routers import SimpleRouter,DefaultRouter
# 2. 实例化
"""
两种类的区别
1.SimpleRouter    生成了可以访问的路径
2.DefaultRouter   生成了可以访问的路径和一个根路径(api-root)里面存放了 路径的超链接
"""
router = SimpleRouter()
# router = DefaultRouter()

# 3. 注册
"""第一个参数路径不用带/  ,
   第二个参数视图类
   第三个参数是别名,一般与路径名相同,"""
router.register('books',views.BookView,'books')

# 4 在urlpatterns中注册  两种方式
urlpatterns = [
    path('admin/', admin.site.urls),
]


"""
1. urlpatterns += router.urls
2. path('api/v1/',include(router.urls))
  - 可以在路由中添加额外的标识api/vi
"""
urlpatterns += router.urls

from django.urls import path,include  # 第二种用的比较多
urlpatterns = [
    path('api/v1/',include(router.urls)),
]


自动生成路由的本质

本质就是自动做映射,视图类中要有5个接口方法的几个或更多个(自己编写的)
get--- list
get--- retrieve
put--- update
post--- create
delete--- destory
继承ModelViewSet,ReadOnlyModelViewSet可以自动生成
继承9个视图子类+配合ViewSetMixin   才可以自动生成


继承ViewSetMixin+ GenericAPIView+5个视图扩展类  才能自动生成
GenericViewSet 内部包含了GenericAPIView,ViewSetMixin 
 " 我们可以直接使用 GenericViewSet+视图扩展类"

action装饰器

注意:不是as_view的actions参数。

可以写在视图类的中,可以自动生成路由


# action装饰器路由编写
# 方式一:手动写
path('send/',views.SendView.as_view({'get':'send_msg'})),

# 方式二:在外面使用register注册,需要在视图函数内使用action装饰器
from rest_framework.routers import SimpleRouter,DefaultRouter
router = SimpleRouter()
router.register('send',views.SendView,'send')
path('api/v1/',include(router.urls)),

视图
基于 ViewSet 编写
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
class SendView(ViewSet):
    """    action 参数
    methods  指定请求方式传列表,列表内可以填多个
    detail  只能传True False
                   -False 不带id路径 只能生成 send/send_msg/
                   -True  带id的路径 send/pk/send_msg/ 需要在视图类中添加参数pk
    url_path  路径 send/ 后面的名字,默认方法名
    url_name  别名反向解析使用"""
    @action(methods=['GET','POST'],detail=True,url_path='haha',url_name='send_msg')
    def send_msg(self,request,pk):
        # query_params 含有路由携带的参数
        phone = request.query_params.get('phone')
        print(request.query_params)
        return Response({'code':100,'msg':'发送成功'})

扩展

 # 补充:
	-1 不同请求方式可以使用不同序列化类
    -2 不同action使用不同序列化类
class SendView(GenericViewSet):
    queryset = None
    serializer_class = '序列化类'
	
    def get_serializer(self, *args, **kwargs):
        if self.action=='lqz':
            return '某个序列化类'
        else:
            return '另一个序列化列'
    @action(methods=['GET'], detail=True)
    def send_sms(self, request,pk):
        print(pk)
        phone = request.query_params.get('phone')
        print('发送成功,%s' % phone)
        return Response({'code': 100, 'msg': '发送成功'})

    @action(methods=['GET'], detail=True)
    def lqz(self,request):  # get
        # 序列化类
        pass

    @action(methods=['GET'], detail=True)
    def login(self,request):  # get
        # 序列化类
        pass
测试伪代码
class SendView(GenericViewSet):
    queryset = Book.objects.all()
    serializer_class = '序列化类'

    # 当有多个相同请求的方法,需要重写get_serializer,因此时的action被ViewSetMixin的view映射成了方法名
    def get_serializer(self):
        if self.action == 'login':
            return print('序列化类1')
        else:
            return print('序列化类2')

    @action(methods=['GET'], detail=False)
    def send_msg(self, request):
        self.get_serializer()
        return Response('send_msg')

    @action(methods=['GET'],detail=False)
    def login(self, request):
        self.get_serializer()
        return Response('login')

    @action(methods=['POST'],detail=False)
    def register(self, request):
        return Response('register')

posted @ 2023-02-06 20:32  李阿鸡  阅读(44)  评论(0编辑  收藏  举报
Title