跳转至

REST framework入坑(11)-Routers(路由)

  • 使用router 快速生成请求方式与动作的映射
  • REST framework提供了两个router: SimpleRouter, DefaultRouter

!!!注意踩过的坑

  • 自动生成的路由时, 在路径的后面不需要加 ' / '
  • 一定要把 urlpatterns.extend(router.url) 整合的过程放到,最后一步!!!, 不然就会覆盖掉前面路径前缀相同的, 因为自动生成的路径比如router.register(r'students', StudentsInfoViewSet, base_name='students'), 此时如果路由请求students/info(得到用户的所有的info信息),这时, Django会把此次请求分发给router里面的视图,并且把info 当作lookup_field传进去,去数据库找, 肯定找不到的,因为本身接受的是pk值,按照pk值取数据库找,就不会进入到我们本身为rstudents/info/^写的视图中
  • 总之就是避免前缀重复的路由,导致混淆,解决办法就是把router 生成的路由一步到位 直接放到最后

生成的规则

对上面踩过的坑进行的补充

  • router.register(r'students', StudentsInfoViewSet, base_name='students') 生成的路由,如果一个请求students/2/info/ 那么这个请求会进入到这个视图中查找 info 方法并 传进去lookup_field(PK) 为 2 就变成了^students/{pk}/info/$
  • 自定义的动作方法在router生成中中会自动的转化成路径,所以要求前端请求的路径需要和我们方法的名字相同
  • Demo
# 导入
from rest_framework import routers
# 创建router对象
router = routers.SimpleRouter()
# 开始为请求路径注册, 注意不需要加斜杠
router.register(r'students', StudentsInfoViewSet, base_name='students')
# 列表正常extend整合另一张列表即可 添加路由对象里自动生成的路由到urlpatterns
urlpatterns.extend(router.url)
  • 具体规则 register(prefix, viewset, base_name)
  • prefix 该视图集的路由前缀
  • viewset 视图集
  • base_name 路由名称的前缀
  • 上面的代码会生成如下路由格式
^students/$    name: student-list
^students/{pk}/$   name: student-detail

自定义action映射

自定义的动作方法在router生成中中会自动的转化成路径,所以要求前端请求的路径需要和我们方法的名字相同

class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    queryset = studentInfo.objects.all()
    serializer_class = studentInfoSerializer
    @action(methods=['get'], detail=False)
    def latest(self, request):
        ...
    @action(methods=['put'], detail=True)
    def info(self, request, pk):
    ...
  • 自动生成的路由:
^students/latest/$    name: sutdent-latest
^studetns/{pk}/info/$  name: student-info

DefaultRouter与SimpleRouter的区别

DefaultRouter与SimpleRouter的区别是, DefaultRouter会多附带一个默认的API根视图, 返回一个包含所有列表视图的超链接响应数据

  • SimpleRouter 99575-g4xkg8q4wap.png
  • DefaultRouter 72257-i0azq24wa7o.png