drf-路由

发布时间 2023-09-05 19:51:13作者: Maverick-Lucky

一、路由routers

  对于视图集,我们除了自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮我们快速注册路由信息。

之前路由写法:
  path('books/', BookView.as_view())

以后一旦继承了ViewSetMixin,就变成了:

  path('publish/', PublishView.as_view({'get': 'list', 'post': 'create'}))

这样写起来,做映射,可能有些麻烦,于是drf,帮咱们封装了两个路由类---》可以帮助咱们快速生成之前咱们写的映射关系。

REST framework提供了两个router

  • SimpleRouter
  • DefaultRouter

###### 必须是继承ViewSetMixin+APIView及其子类才能自动生成 SimpleRouter DefaultRouter

1.1 使用方法

# 大前提:必须是继承ViewSetMixin+APIView及其子类才能自动生成

1# urls.py中

#### 1 导入路由类

  from rest_framework.routers import SimpleRouter, DefaultRouter

#### 2 类实例化得到对象

  router = SimpleRouter()

#### 3 自动生成路由,调用对象的某个方法,完成跟视图类的对应关系,映射路由

  router.register('publish', PublishView, 'publish')

# router.register('books', BookView, 'books') # 后期可以注册更多

  router.register('user',UserView,'user')

##### 4 把自动生成的路由,加到总路由中

  urlpatterns = urlpatterns + router.urls  # 两个列表直接相加

### 第四步可以这样写: path('api/v1/', include(router.urls)),   # http://127.0.0.1:8008/api/v1/user/register/--->post

SimpleRouter, DefaultRouter区别

  -DefaultRouter生成的路径多一个根路径 api-root
  -DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据
以后就用:SimpleRouter就可以

二、action装饰器

在视图集中,如果想要让Router自动帮助我们为自定义的动作生成路由信息,需要使用rest_framework.decorators.action装饰器。

以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。

1. 作用:为视图类中的方法做路径的映射,这些方法排除:create、list、destory、update、retrieve

2. 使用方式
  @action(methods=['POST'],detail=False)
  def register(self, request):
    return Response('register')

3. 自动生成:

  http://127.0.0.1:8008/user/register/---->post--->就会执行register  

4. action装饰器可以接收两个参数:

  • methods: 声明该action对应的请求方式,可以写多个,列表传递

  • detail:声明该action的路径路径中是否带id号,及是否是:xxx/<pk>/action方法名/
    • True 表示路径格式是xxx/<pk>/action方法名/
    • False 表示路径格式是xxx/action方法名/

  比如:

  http://127.0.0.1:8008/user/register/    # detail=False

  http://127.0.0.1:8008/user/4/register/  # detail=True

 

三、以后继承ModelViewSet可能会重写好多方法

比如说:重写list方法,定制自己的list方法

class PublishView(ModelViewSet):
    
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    # 重写list方法
    def list(self,requset,*args,**kwargs):
    
        res = super().list(request, *args, **kwargs)
        return res({'code':200,'msg':成功','result':res.data})

可以通过重写get_serializer_class方法来选择对应方法所需要的序列化类

通过判断请求方式来选择,想要序列化使用PublishSerializer,反序列化使用 WritePublishSerializer 

这里还可以通过通过action参数,限制视图类中某个方法使用的序列化类是哪个 

def get_serializer_class(self):
    print(self.action)  # 这个视图类的action属性,是当次请求方式的方法名的字符串
    if self.request.method =='POST': # 
         return WritePublishSerializer
    else:
        return self.serializer_class

还可以重写perform_create 在保存对象前做拦截,做日志记录等

### 重写perform_createdef
perform_create(self, serializer):
    serializer.save()