DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • Django

  • 第一次学drf

    • Postman和restful
    • APIView
    • Serializer
    • ModelSerializer
    • drf的请求与响应
    • drf的视图组件
    • drf的路由组件
      • 快速实现接口
      • 自动生成路由
      • action的使用
      • 扩展: .action
    • 认证权限频率
    • 过滤排序分页异常
    • 源码分析
    • jwt
    • 大回顾
    • 零散的知识点
  • 第二次学drf

  • 温故知新

  • flask

  • 后端
  • 第一次学drf
DC
2023-11-10
目录

drf的路由组件

# 快速实现接口

models.py

from django.db import models


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)


class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()
    publish = models.ForeignKey(to=Publish, on_delete=models.CASCADE)
 

"""
迁移数据库,通过各自路由的5个接口添加的数据,当然也可以手动添加.

1,南京出版社,南京
2,东京出版社,东京

1,三国演义,11,1
2,红楼梦,22,2
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

serializer.py

from rest_framework import serializers
from . import models


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'


class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        fields = '__all__'
1
2
3
4
5
6
7
8
9
10
11
12
13
14

views.py

from rest_framework.viewsets import ModelViewSet
from .models import Book, Publish
from .serializer import BookSerializer, PublishSerializer


# -- 实现图书的五个接口
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer


# -- 实现出版社的五个接口
class PublishView(ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

urls.py

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
    path('books/<int:pk>', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    path('publish/', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
    path('publish/<int:pk>', views.PublishView.as_view({'get': 'retrieve',
                                                        'put': 'update',
                                                        'delete': 'destroy'})),
]
1
2
3
4
5
6
7
8
9
10
11
12
13

# 自动生成路由

一共要经历四步!!

from django.contrib import admin
from django.urls import path, include
from app01 import views

# -- step1:导入
from rest_framework.routers import DefaultRouter, SimpleRouter

# -- step2:实例化得到router对象
#    SimpleRouter和DefaultRouter用哪个都行.它两用法一致,功能几乎一样
router = SimpleRouter()
# router = DefaultRouter()  # -- 它自动生成的路由多一条,多个根路径

# -- step3:注册视图集
#    - 参数一:路径前缀
#    - 参数二:视图类
#           (★★★ 该视图类必须继承ViewSet类或其子类,也就是说视图类继承的父类以及父类的父亲直到object
#             只要有ViewSetMixin + APIView就可以 因为ViewSet = ViewSetMixin + APIView)
#    - 参数三:别名(反向解析的时候使用 几乎不用)
router.register('books', views.BookView, basename='books')
router.register('publish', views.PublishView, basename='publish')
# 查看注册视图集后生成的路由
print(router.urls)

# -- step4:将自动生成的路由列表添加到总路由中,有两种方式!
#    - 方式一: 使用路由分发的方式添加! include.
urlpatterns = [
    path('admin/', admin.site.urls),
    # -- 自动生成以下几条路由!!
    # path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
    # path('books/<int:pk>', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    # path('publish/', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
    # path('publish/<int:pk>', views.PublishView.as_view({'get': 'retrieve',
    #                                                     'put': 'update',
    #                                                     'delete': 'destroy'})),
    path('', include(router.urls))
]
#    - 方式二:
#      两列表相加,就相当于extend!
# urlpatterns += router.urls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# action的使用

前面我们成功生成了路由地址[增/删/改/查一条/查多条的功能]
若要给自定义方法生成路由, 则需要进行action动作的声明!
以action装饰器装饰的方法名会作为action动作名, 与list、retrieve等同..

urls.py

from django.contrib import admin
from django.urls import path, include
from app01 import views
from rest_framework.routers import SimpleRouter, DefaultRouter

router = SimpleRouter()
router.register('books', views.BookView, basename='books')
router.register('publish', views.PublishView, basename='publish')
router.register('test', views.TestView, basename='test')

urlpatterns = [
    path('admin/', admin.site.urls),
    # -- 手动自己写!
    #    思考一个问题,若不手动自己写,那自动生成的,如何知道 as_view({}) 字典里的对应关系呢?
    #    也就是不知道用什么请求get/post/put.. 触发login方法.
    #    解决方案:在视图类里使用action装饰器!!
    # path('test/', views.TestView.as_view({'get': 'login'})),
]
urlpatterns += router.urls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

views.py

from rest_framework.viewsets import ModelViewSet
from .models import Book, Publish
from .serializer import BookSerializer, PublishSerializer
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework.decorators import action


# -- 实现图书的五个接口
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer


# -- 实现出版社的五个接口
class PublishView(ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer


# -- 回顾下:继承了ViewSet以后,里面的方法可以随便命名!
class TestView(ViewSet):
    """action的参数
    methods -- 做一个映射,也就是http的请求方式会映射当前方法
               这里get和post请求都会触发login
               相当于 path('test/', views.TestView.as_view({'get': 'login','post': 'login'})),
    detail -- True或False
              False - /test/login     类似于获取所有的视图类 多条
              True -  /test/pk/login  类似于获取详情的视图类 单条
    url_path -- 访问的路径“可写正则”,可以不写, ★若不写,默认值就是方法名,默认访问的路径是方法名!!
                -- 若detail=False
                   若 在路由层router.register('test', ..) 以及 这里的url_path='login'
                   那么 /test/login 路径下的get或post请求就会触发login方法的执行!
                   Ps:若使用的是路由分发的方式将自动生成的路由列表添加到总路由中.
                       eg: - path('wow', include(router.urls)) 、
                           - router.register('test', ..)、
                           - url_path='login'
                           那么访问的路径应该是 /wow/test/login
                -- 若detail=True
                   若 在路由层router.register('test', ..) 以及 这里的url_path='login'
                   那么 /test/pk/login 路径下的get或post请求就会触发login方法的执行!
                   Ps:若使用的是路由分发的方式将自动生成的路由列表添加到总路由中.
                       eg: - path('wow', include(router.urls)) 、
                           - router.register('test', ..)、
                           - url_path='login'
                           那么访问的路径应该是 /wow/test/pk/login
    url_name -- 别名.(反向解析时用)
    """

    # @action(methods=['GET', 'POST'], detail=False, url_path='login', url_name='login')
    @action(methods=['GET', 'POST'], detail=False)
    def login(self, request):
        return Response('登陆成功!')

    # @action(methods=['GET', 'PUT', 'DELETE'], detail=True)
    # def login(self, request, pk):
    #     return Response('登陆成功!')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

# 扩展: .action

动态的替换掉方法使用的序列化类/切换序列化器

from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import Test
from .serializer import TestSerializer, OtherSerializer


# -- 视图类继承了GenericViewSet
#    视图类里可以有很多很多方法,不一定都要用BookSerializer这个序列化类来序列化!
#    所以我们可以重写get_serializer_class方法!!
class TestView(GenericViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

    def get_serializer_class(self):
        # -- 当前视图类的对象中就有action属性,我们可以通过这个属性判断当前请求会执行哪个视图类中的方法!
        # -- 动态的替换掉方法使用的序列化类
        if self.action == 'login':
            return OtherSerializer
        else:  # -- 否则使用原来的序列化类
            # return super().get_serializer_class()
            return self.serializer_class

    @action(methods=['GET', 'POST'], detail=False)
    def login(self, request):
        return Response('登陆成功!')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

drf的视图组件
认证权限频率

← drf的视图组件 认证权限频率→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式