首页 > 其他分享 >DRF之路由组件

DRF之路由组件

时间:2024-04-21 22:14:04浏览次数:17  
标签:books app01 import 组件 path book 路由 DRF

一、路由的写法

1、原始写法

(1)介绍

  • 是指手动编写路由规则的方式。
  • 使用path()函数或re_path()函数来定义路由规则,并将其与对应的视图函数或类关联起来。

(2)示例

  • 假设有一个名为book的应用,它包含了一个处理图书列表的视图函数book_list,以及一个处理单个图书详情的视图函数book_detail
  • 我们可以通过以下方式手动编写路由规则:
from django.urls import path

from book.views import book_list, book_detail

urlpatterns = [
    path('books/', book_list, name='book_list'),
    path('books/<int:book_id>/', book_detail, name='book_detail'),
]
  • 在这个例子中
    • 第一条路由规则匹配到/books/路径,并将其与book_list视图函数关联起来。
    • 第二条路由规则匹配到/books/<int:book_id>/路径,其中<int:book_id>是一个路径参数,用于匹配一个整型的图书ID,并将其传递给book_detail视图函数。

2、手动映射的写法

(1)介绍

  • 路由器将HTTP方法与视图集中的相应操作方法进行映射。
  • 在使用路由器时,需要先定义一个视图集,然后将其与路由器关联起来。
  • 最后,在URL配置中使用路由器生成的路由规则。

(2)示例

from rest_framework.routers import DefaultRouter
from book.views import BookModelViewSet

urlpatterns = [   
    path("books/", BookModelViewSet.as_view({"get": "list","post": "create"})),
    path("books/<int:pk>/", BookModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
]

3、小结

  • 手动编写路由规则更加灵活,可以对每个URL路径指定具体的视图函数或类。
  • 可以根据需求选择手动编写路由规则或使用路由器自动生成路由规则。
  • 使用路由器可以简化代码,特别适用于处理一组相关操作的视图函数或类。

二、自动生成路由

前提:继承了ViewSetMixin。对于视图集ViewSet,除了可以手动进行URL配置指明请求方式与action处理函数之间的对应关系外,还可以使用路由Router来自动生成路由信息。

在 Django REST framework 中,SimpleRouterDefaultRouter 都是用于简化 URL 配置和路由管理的工具,它们可以帮助开发者快速创建符合 RESTful 设计原则的 API 路由。

1、SimpleRouter

(1)使用步骤

  • 导入一个路由类
from rest_framework.routers import SimpleRouter
  • 实例化得到对象
router=SimpleRouter()
  • 执行对象的方法
router.register('books',BookView,'books')
  • 对象.属性 拿到值
print(router.urls)
urlpatterns = [
    path('request/', BookView.as_view()),
    path('publish/', PublishView.as_view({'get': 'login'})),
]
  • 把自动生成的路由,放到 urlpatterns中
方案一:urlpatterns+=router.urls

方案二:urlpatterns = [
    path('', include(router.urls)),
]  # 用来代替上面的urlpatterns,优势在于我前面还可以再加前缀

比如我用方案一生成的url是 http://127.0.0.1:8000/app01/books/
        
path('api/v1/', include(router.urls))  # 添加前缀        
而用方案二我可以生成 http://127.0.0.1:8000/app01/api/v1//books/

image

  • 4和5是我们自动生成的路由

  • SimpleRouter自动生成的路由不包括自定义的视图函数login,只会生成:(指定的prefix:books前缀拼接xxx路径,单独访问127.0.0.1:8000:/app01/会返回404报错)

    • (1)app01/books/$ [name='books-list']–--> 相当于re_path(r'^app01/books/$')
    • (2)app01/^books/(?P<pk>[^/.]+)/$ [name='books-detail'] –--> 相当于re_path(r'^app01/book/<pk>/$')

(2)生成URL的方式

image

2、DefaultRouter

(1)使用步骤

  • 导入一个路由类
from rest_framework.routers import DefaultRouter
  • 实例化得到对象
router=DefaultRouter()
  • 执行对象的方法
router.register('books',BookView,'books')
  • 对象.属性 拿到值
print(router.urls)
urlpatterns = [
    path("books/", BookView.as_view({"get": "list", "post": "create"})),
    path("books/<int:pk>/", BookView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
]
  • 把自动生成的路由,放到 urlpatterns中
方案一:urlpatterns+=router.urls

方案二:urlpatterns = [
    path('', include(router.urls)),
]  # 用来代替上面的urlpatterns,优势在于我前面还可以再加前缀

比如我用方案一生成的url是 http://127.0.0.1:8000/app01/books/

path('api/v1/', include(router.urls))  # 添加前缀
而用方案二我可以生成 http://127.0.0.1:8000/app01/api/v1//books/

image

  • 4和6是SimpleRouter自动生成的路由

  • 5和7是另一种格式正则表达式,再加上一个根路由

  • DefaultRouter自动生成的路由也不包括自定义的视图函数login

    • (1)app01/ ^books\.(?P<format>[a-z0-9]+)/?$ [name='books-list']–--> 相当于re_path(r'^app01/books/$')
    • (2)app01/ ^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='books-detail'] –--> 相当于re_path(r'^app01/book/<pk>/$')

(2)生成URL的方式

image

(3)与SimpleRouter不同的地方

  • 127.0.0.1:8000/app01/books.json可以得到原生的json数据

image

  • 根路由,访问127.0.0.1:8000不会返回404报错,而是返回下面的页面

image

三、使用action装饰器自定义详细路由

作用:修饰自定义视图函数,使之能够进行自动路由映射

因为上面两种自动映射路由方法都不会映射自定义视图方法所以我们选择装饰器。
@action(methods=['get'], detail=False, url_path='latest')

  • urls.py
path("books/", BookModelViewSet.as_view({"get": "latest"})),
  • views.py
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from app01.models import Book, Publish
from app01.serializers import BookSerializer, PublishSerializer
# action作用:修饰自定义视图函数,使之能够进行自动路由映射
from rest_framework.decorators import action


class BookModelViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # methods: 映射的请求方式
    # url_path: 路径拼接尾缀,默认值是函数名字
    # detail:
    #      True ---> 路径拼接是: 前缀(prefix) + pk正则分组 + 尾缀(url_path)
    #      False ---> 路径拼接是: 前缀(prefix) + 尾缀(url_path)
    @action(methods=['get'], detail=False, url_path='latest')
    def latest(self, request, *args, **kwargs):
        book = self.queryset.latest('id')  # 最新发布的书
        serializer = self.get_serializer(instance=book)
        return Response(data=serializer.data)

image

四、视图类对象.action

self.action:可以看出请求的是谁,根据不同的请求返回不同的序列化器。(这种场景使用概率比较小)

使用:

from rest_framework.viewsets import ModelViewSet
from testdjango.models import BookInfo
from book_drf.serializer import BookSerializer
from rest_framework.response import Response
 
 
class Books(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookSerializer
 
    # 根据这方法可以看出请求的是谁,返回哪个序列化器
    def get_serializer_class(self):
        if self.action == 'lastdata':
            return BookSerializer
        else:
            return BookSerializer
 
    # 定义如果超出那五个方法之外的方法,需要使用action装饰器
    @action(methods=['get'], detail=True)
    def lastdata(self, request, pk):
        # 使用self.action 获取请求的是哪个方法,可以根据请求的是哪个
        print(self.action)
        book = BookInfo.objects.get(id=pk)
        ser = self.get_serializer_class(book)
        return Response(ser.data)

标签:books,app01,import,组件,path,book,路由,DRF
From: https://www.cnblogs.com/xiao01/p/18149457

相关文章

  • 分页组件
    分页组件​ 查询所有,才有分页功能(例如网站的下一页功能,app下挂加载更多)PageNumberPagination基本分页重要类属性page_size=api_settings.PAGE_SIZE(每页显示条数)page_query_param='page'(查询时用的参数)page_size_query_param=None(更改返回条数)max_page_size=......
  • 视图组件
    两个视图基类APIView#APIView是rest-framwork提供的所有视图类的基类,它继承自django的View类#在APIView中仍然以常规的类视图定义方法来实现get()、post()...请求方式的方法APIView和View的区别传入到视图方法中的请求对象是rest-framwork的Reqeust类的对象,而不是djang......
  • 路由组件
    Routers​ 对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系,还可以使用Routers类来快速实现路由的创建SimpleRouter(常用)DefaultRouter(用的少)#方式一#1.导入Routers类fromrest_framework.routersimportDefaultRouter#2.实例化对......
  • 第27天:安全开发-PHP应用&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞 - Shortcut
     https://www.kancloud.cn/manual/thinkphp5_1/354000ThinkPHP-Vuln-master ......
  • 在React中的函数组件和类组件——附带示例的对比
    在React中,创建组件有两种主要方式:函数组件和类组件。每种方式都有自己的语法和用例,尽管随着ReactHooks的引入,它们之间的差距已经显著缩小。但选择适当的组件类型对于构建高效和可维护的React应用程序仍然非常关键。在本文中,我们将探讨函数和类组件之间的基本区别,清楚地理解它们......
  • vue中ts引入组件,无法找到模块xxx的声明文件。xxx隐式拥有 "any" 类型。
    原因说明简单来说就是ts不认识.vue这个类型,需要定义声明。我刚学ts不是很懂为什么vite官方内写了那么多类型声明就是不写.vue。解决方法在项目根目录下找到env.d.ts文件,这个文件定义类型声明,简单地说就是让ts认识各种类型,尤其是文件。那么解决方法显而易见,我们自定义vue的......
  • Flask路由和蓝图
    Flask路由和蓝图目录Flask路由和蓝图路由定义查看路由信息url_map对象路径参数设置和获取add_url_rule的参数执行流程分析重定向蓝图概述基本使用内部静态文件内部模板目录参考资料路由定义在Flask中,路由用于将HTTP请求与特定的Python函数相匹配。通过定义路由,Flask应用程序可......
  • 鸿蒙HarmonyO实战-ArkUI动画(组件内转场动画)
    ......
  • 微信小程序video在组件中的使用---暂停视频
    首先在wxml文件中设置video的id<videoid='myVideo'src='{{video}}'controls='true'></video>然后在js文件中通过wx.createVideoContext获取VideoContext实例letvideoCtx=nullletapp=getApp()Component({properties:{},......
  • taro 基础组件 video的一些基本情况设置
    <videoclass="section-video-content"id="myVideo"src="http://192.168.10.15:9000/sisterofdc/exam/video/226/test.mp4"@timeupdate='getUpdateTime'></video>function......