drf06 action与路由

一、路由

1 自动路由配置-router

引入

什么是自动路由,自动路由就是继承了viewSetMixin 功能的视图,需要指定action操作,由于配置比较麻烦。
所以就有一种方式可以配置自动路由,不过自动路由只是帮你写好了一些路由映射关系,和普通的写法没区别

使用

前期准备

# models.py 
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8,decimal_places=3)
    author = models.CharField(max_length=32)
    publish = models.CharField(max_length=32)
    
# ser.py 
from rest_framework import serializers
from app04_router import models

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
        extra_kwargs = {
            'id': {'read_only': True}
        }

视图层

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from app04_router.ser import BookSerializer
from app04_router import models
# Create your views here.
class BookModelViewSet(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

路由层 - 重点

from django.contrib import admin
from django.urls import path, re_path
from app04_router import views

# 自动路由设置
# 1.导入路由模块
from rest_framework import routers

# 2.调用简单路由类
rounter = routers.SimpleRouter()
# rounter = routers.DefaultRouter()

# 3.注册路由
# register(self, prefix, viewset, basename=None):
# router.register('前缀','继承自ModelViewSet视图类','别名')
from app04_router import views
rounter.register('books',views.BookModelViewSet) # 不要加斜杠了



urlpatterns = [

]
# 4.配置自动路由
rounter.urls # 自动生成的路由,加入到原路由中

print(rounter.urls)

'''
SimpleRouter()

[<URLPattern '^books/$' [name='book-list']>,
 <URLPattern '^books/(?P<pk>[^/.]+)/$' [name='book-detail']>]
'''

'''
DefaultRouter
[<URLPattern '^books/$' [name='book-list']>,
 <URLPattern '^books\.(?P<format>[a-z0-9]+)/?$' [name='book-list']>, 
 <URLPattern '^books/(?P<pk>[^/.]+)/$' [name='book-detail']>, 
 <URLPattern '^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='book-detail']>,
<URLPattern '^$' [name='api-root']>, <URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>]
'''
# 5.加入到原路由列表中
urlpatterns += rounter.urls # 将自动配置的路由加到原路由中

路由router形成URL的方式

1) SimpleRouter

SimpleRouter

2)DefaultRouter

DefaultRouter

DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。比如使用DefaultRouter时你访问一下http://127.0.0.1:8001/router_stu/ 会看到一个页面,而SimpleRouter会报错,一般都需要有个查看所有接口的页面,所以我们基本都是用的是DefaultRouter。

二、action的相关用法

2.1 视图集中定义附加action动作

在视图集中,除了上述默认的方法动作外,还可以添加自定义动作,进行扩展。

# 以前的用法是在 注册路由的时候,当视图类 继承了ViewSetMixin,那么as_view()就需要指定动作
用法是 xxx.as_view(action={'请求方式':'方法的内存地址'})

# 举例 - 当该请求是get请求的时候,那么就去找 该 名称空间中,是否有list方法的内存地址
  views.BookModelViewSet.as_view(action={'get':'list'})

2.2 视图集中附加action的声明

介绍

在视图集中,如果想要让Router自动帮助我们为自定义的动作生成路由信息,需要使用rest_framework.decorators.action装饰器。

用法

**action(methods=None, detail=None, url_path=None, url_name=None, **kwargs)

methods:http请求方式 - get/post/put/delete/patch/...

detial :

True 表示路径格式是xxx/<pk>/action方法名/

​ `False 表示路径格式是xxx/action方法名/``

**url_path **:不指定默认是装饰的方法名

url_name:反向解析

使用

说明

​ 内容同 自动路由差不多,只有视图层有差异

前期准备

# models.py 
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8,decimal_places=3)
    author = models.CharField(max_length=32)
    publish = models.CharField(max_length=32)
    
# ser.py 
from rest_framework import serializers
from app04_router import models

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
        extra_kwargs = {
            'id': {'read_only': True}
        }

视图层 -重点

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from app04_router.ser import BookSerializer
from app04_router import models
# Create your views here.
class BookModelViewSet(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer
    # action(methods=None, detail=None, url_path=None, url_name=None, **kwargs):

    @action(methods=['get'],detail=True,url_path='query_author') #  detail 控制是否需要传参 类似于 all 或 pk
    def get_fields_data(self,request,pk):
        obj = models.Book.objects.filter(author = pk).first()
        ser = BookSerializer(instance=obj)
        return Response(ser.data)

路由层

from django.contrib import admin
from django.urls import path, re_path
from app04_router import views

# 自动路由设置
# 1.导入路由模块
from rest_framework import routers

# 2.调用简单路由类
rounter = routers.SimpleRouter()
# rounter = routers.DefaultRouter()

# 3.注册路由
# register(self, prefix, viewset, basename=None):
# router.register('前缀','继承自ModelViewSet视图类','别名')
from app04_router import views
rounter.register('books',views.BookModelViewSet) # 不要加斜杠了



urlpatterns = [

]
# 4.配置自动路由
rounter.urls # 自动生成的路由,加入到原路由中

print(rounter.urls)

'''
SimpleRouter()

[<URLPattern '^books/$' [name='book-list']>,
 <URLPattern '^books/(?P<pk>[^/.]+)/$' [name='book-detail']>]
'''

'''
DefaultRouter
[<URLPattern '^books/$' [name='book-list']>,
 <URLPattern '^books\.(?P<format>[a-z0-9]+)/?$' [name='book-list']>, 
 <URLPattern '^books/(?P<pk>[^/.]+)/$' [name='book-detail']>, 
 <URLPattern '^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='book-detail']>,
<URLPattern '^$' [name='api-root']>, <URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>]
'''
# 5.加入到原路由列表中
urlpatterns += rounter.urls # 将自动配置的路由加到原路由中

三、补充:路由的三种写法

1.基本写法

使用django传统路由:DVBCVB

# 1.在项目的urls.py 分app 做路由分发
re_path(r'^app01/', include('app01.urls')
        
# 2.向app的urls.py 中
# DVB
 path('index/', views.index)
# CVB
 path('books/',views.BookGenericAPIView.as_view()),
 re_path(r'^books/(?P<pk>\d+)/',views.BookGenericAPIView.as_view()),

2.使用自动路由1

-自动生成路由
	-SimpleRouter
    -DefaultRouter
    -使用:
    	# 第一步:导入routers模块
        from rest_framework import routers
        # 第二步:有两个类,实例化得到对象
        # routers.DefaultRouter 生成的路由更多
        # routers.SimpleRouter
        router=routers.SimpleRouter()
        # 第三步:注册
        # router.register('前缀','继承自ModelViewSet视图类','别名')
        router.register('books',views.BookViewSet) # 不要加斜杠了
        # 第四步:将注册的路由与urlpatterns 合并
        urlpatterns+=router.urls  # 加在 urlpatterns 后面

3.自动路由方式2(不常用)

-自动生成路由
	-SimpleRouter
    -DefaultRouter
    -使用:
    	# 第一步:导入routers模块
        from rest_framework import routers
        # 第二步:有两个类,实例化得到对象
        # routers.DefaultRouter 生成的路由更多
        # routers.SimpleRouter
        router=routers.SimpleRouter()
        # 第三步:注册
        # router.register('前缀','继承自ModelViewSet视图类','别名')
        router.register('books',views.BookViewSet) # 不要加斜杠了
        
        # 第四步:在 urlpatterns 中写以下内容
        path('', include(router.urls)),  # 第二种方式 # 加在 urlpatterns 后面
-django传统的路由(cvb路由)path('test/', views.TestView.as_view()),
-只要继承ViewSetMixin:path('books/', views.BookViewSet.as_view({'get':'list','post':'create'})),
-自动生成路由
	-SimpleRouter
    -DefaultRouter
    -使用:
    	# 第一步:导入routers模块
        from rest_framework import routers
        # 第二步:有两个类,实例化得到对象
        # routers.DefaultRouter 生成的路由更多
        # routers.SimpleRouter
        router=routers.SimpleRouter()
        # 第三步:注册
        # router.register('前缀','继承自ModelViewSet视图类','别名')
        router.register('books',views.BookViewSet) # 不要加斜杠了
        urlpatterns+=router.urls
posted @ 2023-05-27 09:34  派森的猫  阅读(86)  评论(0)    收藏  举报