Django REST framework 源码分析-路由详解(Routers)

打印 上一主题 下一主题

主题 806|帖子 806|积分 2428

Django REST framework 源码分析-路由详解(Routers)




  • SimpleRouter
  • DefaultRouter
  • 以上两种路由注册方式必须配合视图集举利用用
  • action 装饰器方式生成路由
路由分发方式



  • 方式一
  1. path('', include(router.urls)),
复制代码


  • 方式二
  1. from rest_framework import routers
  2. from myapp.viewsets import IndexActinosView
  3. # 1.实例化路由对象
  4. router = routers.SimpleRouter()
  5. # 2.注册生成路由
  6. router.register('actions', IndexActinosView, basename='actions')
  7. # 3.添加路由
  8. urlpatterns = []
  9. urlpatterns += router.urls
复制代码
SimpleRouter路由生成



  • 创建viewset
  1. from rest_framework.viewsets import ModelViewSet
  2. from myapp.serializer import IndexActionsSerializer
  3. from myapp.models import IndexActions
  4. class IndexActinosView(ModelViewSet):
  5.     serializer_class = IndexActionsSerializer
  6.     queryset = IndexActions.objects.all()
复制代码


  • 注册路由
  1. from rest_framework import routers
  2. from myapp.viewsets import IndexActinosView
  3. # 1.实例化路由对象
  4. router = routers.SimpleRouter()
  5. # 2.注册生成路由
  6. router.register('actions', IndexActinosView, basename='actions')
  7. # 3.添加路由
  8. urlpatterns = []
  9. urlpatterns += router.urls
复制代码


  • 生成路由
  • 虽然你只看到两条路由, 但着实每一条路由背面都映射了可以保留的请求方式及action的映射
  1. #包含:获取列表get,创建一条信息post
  2. app/^actions/$ [name='studentmodel-list']
  3. #包含:获取一条信息get,更新一条信息put,删除一条信息delete
  4. app/^actions/(?P<id>[^/.]+)/$ [name='studentmodel-detail']  
复制代码


  • 路由对象register方法参数先容
  1. # 1.实例化路由对象
  2. router = routers.SimpleRouter()
  3. # 2.注册生成路由
  4. router.register('路由命名', 视图集, basename='路由名称前缀')
复制代码
DefaultRouter路由生成



  • 在Django REST framework(DRF)中,DefaultRouter 是 routers 模块提供的一个类,它用于自动为你的应用中的视图集(ViewSets)生成URL模式。使用 DefaultRouter 可以极大地简化URL设置的复杂性,特别是当你的应用包含多个与资源相关的视图集时。
  • DefaultRouter 为每个视图集自动生成以下URL模式:

    • 列表视图(list view):返回资源对象列表
    • 详情视图(detail view):返回单个资源对象
    • 创建视图(create view):创建新的资源对象
    • 更新视图(update view):更新现有的资源对象
    • 删除视图(delete view):删除资源对象

  • 创建viewset
  1. from rest_framework.viewsets import ModelViewSet
  2. from myapp.serializer import BookSerializer
  3. from myapp.models import Book
  4. class BookModelViewSet(ModelViewSet):
  5.     serializer_class = BookSerializer
  6.     queryset = Book.objects.all()
复制代码


  • 注册路由
  1. #urls.py
  2. from rest_framework import routers
  3. from myapp.viewsets import BookModelViewSet
  4. # 1.实例化路由对象
  5. router = routers.DefaultRouter()
  6. # 2.注册生成路由
  7. router.register('book', BookModelViewSet)
  8. # 3.添加路由
  9. urlpatterns = []
  10. urlpatterns += router.urls
复制代码


  • 生成路由
  1. app/^actions/$ [name='studentmodel-list']
  2. app/^actions\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-list']
  3. app/^actions/(?P<id>[^/.]+)/$ [name='studentmodel-detail']
  4. app/^actions/(?P<id>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-detail']
  5. app/ [name='api-root']
  6. app/<drf_format_suffix:format> [name='api-root']
复制代码


  • 我们看到中央还多了一些路由,是带有format正则匹配的,这些是用来获取纯粹json格式数据
  1. # 例 http://127.0.0.1:8000/app/actions.json
  2. app/^actions\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-list']
  3. app/^actions/(?P<id>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-detail']
  4. app/<drf_format_suffix:format> [name='api-root']
复制代码
根路由概念



  • 根路由是一个特殊的路由,用于处理对网站根目次的请求,并通常列出所有可用的API端点。
  • 通常是一个特殊的路由,它位于路由系统的最顶层,用于处理对网站根目次(如/)的请求。在Django REST framework中,使用DefaultRouter时,会自动生成一个根路由,该路由会列出所有可用的API端点。这使得开发者能够方便地查看和理解API的结构。
两种路由生成方式区别



  • SimpleRouter:最基本的路由映射方式,只会将视图集具备的混入类功能举行路由的生成
  • DefaultRouter:对比与SimpleRouter更加高级,包含有drf根页面的路由,不只是视图集所包含的视图部分
额外操作的路由 (Routing for extra actions)



  • 路由注册
  1. from rest_framework.viewsets import ModelViewSet
  2. from myapp.permissions import IsAdminOrIsSelf
  3. from rest_framework.decorators import action
  4. class UserViewSet(ModelViewSet):
  5.     ...
  6.     @action(methods=['post'], detail=True, permission_classes=[IsAdminOrIsSelf], url_path='set-password', url_name='set_password')
  7.     def set_password(self, request, pk=None):
  8.         ...
复制代码


  • 路由生成
  1. URL 模式: ^users/{pk}/set-password/$
  2. URL 名称: 'user-set_password'
复制代码
自界说路由器 (Custom Routers)



  • url:表示被路由的 URL 的字符串
  • mapping:HTTP 方法名称到视图方法的映射
  • name:在 reverse 调用时使用的 URL 名称。
  • initkwargs:实例化视图时应传递的任何其他参数的字典。请留意,detail,basename 和 suffix 参数是视图集内省保留的,并也可由可浏览 API 使用来生成视图名称和痕迹链接。
  1. # url参数可能包含以下格式字符串:
  2. {prefix} —— 用于这组路由的 URL 前缀。
  3. {lookup} —— 用于匹配单个实例的查找字段。
  4. {trailing_slash} —— “/” 或空字符串,取决于 trailing_slash 参数。
  5. # name参数可能包含以下格式字符串:
  6. {basename} —— 用于创建的 URL 名称的基础。
复制代码
自界说动态路由 (Customizing dynamic routes)



  • url:表示被路由的 URL 的字符串。
  • name:在 reverse 调用时使用的 URL 名称。大概包含以下格式字符串:
  • initkwargs:实例化视图时应传递的任何其他参数的字典。
  1. # url参数可能包含以下格式字符串:
  2. {url_path} —— 格式字符串
  3. # name参数可能包含以下格式字符串:
  4. {basename} —— 用于创建的 URL 名称的基础。
  5. {url_name} —— 提供给 @action 的 url_name。
复制代码
示例: 只路由 list 和 retrieve 操作,不使用斜杠约定



  • 自界说路由
  1. from rest_framework.routers import Route, DynamicRoute, SimpleRouter
  2. class CustomReadOnlyRouter(SimpleRouter):
  3.     """
  4.     用于只读 API 的路由器,不使用尾部斜杠。
  5.     """
  6.     routes = [
  7.         Route(
  8.             url=r'^{prefix}$',
  9.             mapping={'get': 'list'},
  10.             name='{basename}-list',
  11.             detail=False,
  12.             initkwargs={'suffix': 'List'}
  13.         ),
  14.         Route(
  15.             url=r'^{prefix}/{lookup}$',
  16.             mapping={'get': 'retrieve'},
  17.             name='{basename}-detail',
  18.             detail=True,
  19.             initkwargs={'suffix': 'Detail'}
  20.         ),
  21.         DynamicRoute(
  22.             url=r'^{prefix}/{lookup}/{url_path}$',
  23.             name='{basename}-{url_name}',
  24.             detail=True,
  25.             initkwargs={}
  26.         )
  27.     ]
复制代码


  • 视图类
  1. from rest_framework import viewsets
  2. from rest_framework.decorators import action
  3. from myapp.serializer import UserSerializer
  4. from myapp.models import User
  5. class UserViewSet(viewsets.ReadOnlyModelViewSet):
  6.     """
  7.     提供标准操作的视图集
  8.     """
  9.     queryset = User.objects.all()
  10.     serializer_class = UserSerializer
  11.     lookup_field = 'username'
  12.     @action(detail=True)
  13.     def group_names(self, request, pk=None):
  14.         """
  15.         返回给定用户所属的所有组名称的列表。
  16.         """
  17.         user = self.get_object()
  18.         groups = user.groups.all()
  19.         return Response([group.name for group in groups])
复制代码


  • 使用自界说路由
  1. from myapp.routers import CustomReadOnlyRouter
  2. router = CustomReadOnlyRouter()
  3. router.register('users', UserViewSet)
  4. urlpatterns = []
  5. urlpatterns += router.urls
复制代码


  • 生成映射
  1. /users        GET        list        user-listAction
  2. /users/{username}        GET        retrieve        user-detail
  3. /users/{username}/group-names        GET        group_names        user-group-names
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

篮之新喜

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表