DRF 路由层

路由层

【1】原始路由

(1)正则re_path

python 复制代码
from django.urls import path, re_path
from book import views

urlpatterns = [
    re_path(r'book/(?P<pk>\d+)?/?$', views.BookAPIView.as_view(), name='book')
]    
  • 示例解释

    • (?P<pk>\d+)是一个命名正则表达式组,它匹配一个或多个数字,并将匹配到的数字作为pk参数传递给视图函数或视图类。

    • 问号?表示这个部分是可选的,所以URL可以是book/book/123/

(2)路径转换器

  • 简单介绍:
    • int:捕获一个整数。
    • str:捕获一个字符串,直到遇到下一个斜杠为止。
    • slug:捕获一个由 ASCII 字母、数字、连字符或下划线组成的字符串。
    • uuid:捕获一个 UUID。
    • path:捕获整个 URL 路径片段,包括斜杠。
python 复制代码
from django.urls import path
from book import views

urlpatterns = [
    path('book/', views.BookAPIView.as_view(), name='book'),
	path('book/<int:pk>/', views.BookOneAPIView.as_view(), name='bookOne'),
]
  • 示例解释
    • <int:pk>是一个路径转换器,它匹配一个整数,并将这个整数作为pk参数传递给视图函数或视图类。
    • 这种写法比使用正则表达式更清晰、更易读。

【2】drf路由写法

(1)手写actions

  • 在视图集中,只要继承了ViewSetMixin,那么就都需要在as_view中传递参数actions
python 复制代码
from book.views import BookViewSet
from django.urls import path, include

urlpatterns = [
    path('book/', views.BookAPIView.as_view({'get': 'list', 'post': 'create'})),
    path('book/<int:pk>/', views.BookAPIView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]
  • 在上面的例子中,BookAPIView是一个继承自ViewSetMixin的视图类。
  • 通过调用as_view()方法并传入一个字典,可以指定每个HTTP方法应该调用的视图集中的哪个动作。
    • 例如,{'get': 'list', 'post': 'create'}表示当使用GET方法访问/book/路径时,将调用BookAPIView中的list动作;当使用POST方法时,将调用create动作。

(2)自动生成router

  • 自动生成router的方式通过使用DRF提供的路由器(如DefaultRouterSimpleRouter),可以大大简化URL的配置过程。
  • 示例:针对上面同样的情况使用SimpleRouter
python 复制代码
from rest_framework.routers import SimpleRouter
from book.views import BookViewSet
from django.urls import path, include

router = SimpleRouter()
router.register(prefix='book', viewset=UserAPIView, basename='book')
urlpatterns += router.urls
  • 参数讲解
  • prefix:用于设置生成 URL 的前缀。
  • viewset :视图集(ViewSet)的实例或者类,应该继承自 rest_framework.viewsets.ViewSet 或其子类(如 ModelViewSet
  • basename:用于生成 URL 名称,在反向解析 URL 时会用到。

(3)加入到路由的两种方式

  • urlpatterns += router.urls
    • 将路由器生成的URL列表直接追加到现有的urlpatterns列表中。
    • 这通常在你已经有了一些手动定义的URL模式,并且想要将路由器生成的URL模式追加到它们之后时使用。
  • path("", include(router.urls))
    • 将路由器生成的URL模式包含在一个特定的路径下。
    • 想要将一组相关的API端点组织在一个共同的URL前缀下时非常有用。只需要在path的第一个参数中添加前缀就可以

(4)SimpleRouterDefaultRouter

  • 相同点

    1. 自动生成URL:两者都能根据视图集中的方法自动生成对应的URL模式,无需手动编写每个URL。
    2. 提供视图集注册 :通过router.register()方法,可以将视图集注册到路由器上,从而生成对应的URL。
  • 不同点

    • 根视图和API界面

      • DefaultRouter:除了为视图集中的每个操作生成URL之外,还会提供一个自动生成的API根视图和可浏览的API界面。这使得开发者可以更容易地查看和测试API。
      • SimpleRouter:只生成与视图集操作对应的URL,不提供自动生成的API根视图和可浏览的API界面。
    • 路由URL数量

      • 由于DefaultRouter提供了额外的根视图和API界面,因此生成的URL数量会比SimpleRouter多。
    • 使用场景

      • DefaultRouter:适用于需要提供一个完整且可浏览的API界面的场景,如开发API供外部调用或内部调试。
      • SimpleRouter:适用于只需要基本的URL映射,而不需要额外API界面的场景,或者当开发者希望减少生成的URL数量以提高性能时。
  • 路径不同

python 复制代码
print(router.urls)
# SimpleRouter
# [<URLPattern '^book/$' [name='book-list']>, <URLPattern '^book/(?P<pk>[^/.]+)/$' [name='book-detail']>]
# DefaultRouter
# [<URLPattern '^book/$' [name='book-list']>, <URLPattern '^book\.(?P<format>[a-z0-9]+)/?$' [name='book-list']>, <URLPattern '^book/(?P<pk>[^/.]+)/$' [name='book-detail']>, <URLPattern '^book/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='book-detail']>, <URLPattern '' [name='api-root']>, <URLPattern '<drf_format_suffix:format>' [name='api-root']>]

【3】aciton装饰器

  • 首先要强调的是必须继承ViewSetMixin的视图类才可以使用

(1)介绍

  • @action装饰器是一个用于在视图集中添加自定义路由和视图方法的强大工具。
  • 语法:@action(detail=False, methods=['get'], url_path='custom-list')
    • detail参数:这个参数决定了该动作是否针对单个实例(True)还是针对集合(False)。
      • 如果detail=True,则URL将包含对象的主键,例如/myendpoint/{pk}/custom-detail/
      • 如果detail=False,则URL将不包含主键,例如/myendpoint/custom-list/
    • methods参数:这个参数是一个列表,指定了支持哪些HTTP方法(如['get'], ['post'], ['put']等)。
    • url_path参数:这个参数是自定义路由的URL部分,它将附加到视图集的URL上。默认是方法名。

(2)示例

  • 要求:在一个视图类中完成登录、注册、修改密码的接口
  • 代码
python 复制代码
from rest_framework.viewsets import ViewSet


class UserAPIView(ViewSet):

    @action(methods=['post'], detail=False)
    def register(self, request):
        return Response({'code': 100, 'msg': '注册成功'})

    @action(methods=['post'], detail=False)
    def login(self, request):
        return Response({'code': 100, 'msg': '登录成功'})

    @action(methods=['post'], detail=False)
    def password(self, request):
        return Response({'code': 100, 'msg': '修改成功'})
相关推荐
不像程序员的程序媛6 小时前
系统cpu内存负载资源分析
运维·服务器·数据库
hhzz6 小时前
Python大数据实战(十六):音乐推荐系统——基于协同过滤算法构建个性化歌单引擎
大数据·人工智能·python·数据挖掘·数据分析
SunnyDays10117 小时前
Python PDF 转 Markdown 详解(转换整个文档,特定页面,表格,扫描 PDF)
python·pdf 转 markdown·pdf 转 md·扫描 pdf 转 md·pdf 表格转 md
Jane Chiu7 小时前
Oracle DBMS_REDEFINITION(在线重定义)
数据库·oracle·分区表
2601_954706497 小时前
云手机 API 自动化实战:Python 批量控机、挂机脚本完整实现
python·智能手机·自动化
全栈前端老曹7 小时前
【MongoDB】安全与权限管理 —— 用户认证、角色权限、SSL 加密
前端·javascript·数据库·安全·mongodb·nosql·ssl
怕孤单的草丛7 小时前
缓存管理面临的主要问题
java·数据库·缓存
我会尽全力 乐观而坚强8 小时前
MySQL零基础入门(二)
数据库·mysql·adb
kali-Myon9 小时前
某校园门禁系统高危 SQL 注入漏洞挖掘复盘
数据库·sql·安全·web安全