当前位置: 首页 > article >正文

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

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

routers

  • SimpleRouter
  • DefaultRouter
  • 以上两种路由注册方式必须配合视图集进行使用
  • action 装饰器方式生成路由

路由分发方式

  • 方式一
path('', include(router.urls)),
  • 方式二
from rest_framework import routers
from myapp.viewsets import IndexActinosView


# 1.实例化路由对象
router = routers.SimpleRouter()
# 2.注册生成路由
router.register('actions', IndexActinosView, basename='actions')
# 3.添加路由
urlpatterns = []
urlpatterns += router.urls

SimpleRouter路由生成

  • 创建viewset
from rest_framework.viewsets import ModelViewSet
from myapp.serializer import IndexActionsSerializer
from myapp.models import IndexActions


class IndexActinosView(ModelViewSet):

    serializer_class = IndexActionsSerializer

    queryset = IndexActions.objects.all()
  • 注册路由
from rest_framework import routers
from myapp.viewsets import IndexActinosView


# 1.实例化路由对象
router = routers.SimpleRouter()
# 2.注册生成路由
router.register('actions', IndexActinosView, basename='actions')
# 3.添加路由
urlpatterns = []
urlpatterns += router.urls
  • 生成路由
  • 虽然你只看到两条路由, 但其实每一条路由后面都映射了可以保留的请求方式及action的映射
#包含:获取列表get,创建一条信息post
app/^actions/$ [name='studentmodel-list']

#包含:获取一条信息get,更新一条信息put,删除一条信息delete
app/^actions/(?P<id>[^/.]+)/$ [name='studentmodel-detail']  
  • 路由对象register方法参数介绍
# 1.实例化路由对象
router = routers.SimpleRouter()
# 2.注册生成路由
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

from rest_framework.viewsets import ModelViewSet
from myapp.serializer import BookSerializer
from myapp.models import Book


class BookModelViewSet(ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()
  • 注册路由
#urls.py
from rest_framework import routers
from myapp.viewsets import BookModelViewSet


# 1.实例化路由对象
router = routers.DefaultRouter() 
# 2.注册生成路由
router.register('book', BookModelViewSet)
# 3.添加路由
urlpatterns = []
urlpatterns += router.urls 
  • 生成路由
app/^actions/$ [name='studentmodel-list']
app/^actions\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-list']
app/^actions/(?P<id>[^/.]+)/$ [name='studentmodel-detail']
app/^actions/(?P<id>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-detail']
app/ [name='api-root']
app/<drf_format_suffix:format> [name='api-root']
  • 我们看到中间还多了一些路由,是带有format正则匹配的,这些是用来获取纯粹json格式数据
# 例 http://127.0.0.1:8000/app/actions.json
app/^actions\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-list']
app/^actions/(?P<id>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-detail']
app/<drf_format_suffix:format> [name='api-root']

根路由概念

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

两种路由生成方式区别

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

额外操作的路由 (Routing for extra actions)

  • 路由注册
from rest_framework.viewsets import ModelViewSet
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import action


class UserViewSet(ModelViewSet):
    ...

    @action(methods=['post'], detail=True, permission_classes=[IsAdminOrIsSelf], url_path='set-password', url_name='set_password')
    def set_password(self, request, pk=None):
        ...
  • 路由生成
URL 模式: ^users/{pk}/set-password/$
URL 名称: 'user-set_password'

自定义路由器 (Custom Routers)

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

# name参数可能包含以下格式字符串:
{basename} —— 用于创建的 URL 名称的基础。

自定义动态路由 (Customizing dynamic routes)

  • url:表示被路由的 URL 的字符串。
  • name:在 reverse 调用时使用的 URL 名称。可能包含以下格式字符串:
  • initkwargs:实例化视图时应传递的任何其他参数的字典。
# url参数可能包含以下格式字符串:
{url_path} —— 格式字符串

# name参数可能包含以下格式字符串:
{basename} —— 用于创建的 URL 名称的基础。
{url_name} —— 提供给 @action 的 url_name。

示例: 只路由 list 和 retrieve 操作,不使用斜杠约定

  • 自定义路由
from rest_framework.routers import Route, DynamicRoute, SimpleRouter

class CustomReadOnlyRouter(SimpleRouter):
    """
    用于只读 API 的路由器,不使用尾部斜杠。
    """
    routes = [
        Route(
            url=r'^{prefix}$',
            mapping={'get': 'list'},
            name='{basename}-list',
            detail=False,
            initkwargs={'suffix': 'List'}
        ),
        Route(
            url=r'^{prefix}/{lookup}$',
            mapping={'get': 'retrieve'},
            name='{basename}-detail',
            detail=True,
            initkwargs={'suffix': 'Detail'}
        ),
        DynamicRoute(
            url=r'^{prefix}/{lookup}/{url_path}$',
            name='{basename}-{url_name}',
            detail=True,
            initkwargs={}
        )
    ]
  • 视图类
from rest_framework import viewsets
from rest_framework.decorators import action
from myapp.serializer import UserSerializer
from myapp.models import User


class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    提供标准操作的视图集
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'username'

    @action(detail=True)
    def group_names(self, request, pk=None):
        """
        返回给定用户所属的所有组名称的列表。
        """
        user = self.get_object()
        groups = user.groups.all()
        return Response([group.name for group in groups])
  • 使用自定义路由
from myapp.routers import CustomReadOnlyRouter


router = CustomReadOnlyRouter()
router.register('users', UserViewSet)
urlpatterns = []
urlpatterns += router.urls
  • 生成映射
/users	GET	list	user-listAction
/users/{username}	GET	retrieve	user-detail
/users/{username}/group-names	GET	group_names	user-group-names

http://www.kler.cn/a/458447.html

相关文章:

  • 嵌入式系统 第七讲 ARM-Linux内核
  • 各个Spring Cloud版本有何主要差异
  • java重装小结
  • elementui的默认样式修改
  • 每天40分玩转Django:Django缓存
  • 【机器学习】回归
  • Docker 开启远程端口访问2375
  • Java的责任链模式在项目中的使用
  • 如何优化求职简历从模板选择到面试准备
  • LeetCode 203:根据值删除节点
  • HDLBits训练6
  • Java爬虫实战:获取亚马逊商品详情
  • 五.Springboot通过AOP实现API接口的签名验证
  • Go IO之文件处理,TCPUDP讲解
  • CF2043b-B. Digits
  • ASP.NET Core Web API Hangfire
  • C# OpenCV机器视觉:漫水填充
  • 春招快速准备和是否考研建议
  • 深度学习实战102-基于深度学习的网络入侵检测系统,利用各种AI模型和pytorch框架实现网络入侵检测
  • STM32高级 以太网通讯案例1:网络搭建(register代码)
  • leetcode 面试经典 150 题:删除有序数组中的重复项
  • 基于SSM的“一汽租车辆共享平台”的设计与实现(源码+数据库+文档+PPT)
  • vue-复制剪贴板
  • pytorch整体环境打包安装到另一台电脑上
  • 高级技巧-使用Mysql 实现根据条件过滤整个分组数据
  • 正则化强度的倒数C——让模型学习更准确