【1】路由写法变化
-
只要继承了ViewSetMixin的子类 ---》 路由写法就要变了
-
变成映射方式
# 视图类 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 # 序列化类 Serializer.py from rest_framework import serializers from app01.models import Book, Publish class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ['name', 'price', 'publish', 'authors', 'publish_detail', 'author_list'] extra_kwargs = { "publish": {"write_only": True}, "authors": {"write_only": True}, "publish_detail": {"read_only": True}, "author_list": {"read_only": True}, } class PublishSerializer(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" # 路由 urls.py from django.urls import path, include from .views import BookView, PublishView urlpatterns = [ path('books/', BookView.as_view({"get": "list", "post": "create"})), path('books/<int:pk>/', BookView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})), ]
【2】自动注册路由方法
-
drf提供了两个视图类,实现不用映射,直接通过类 实例化得到对象方式,自动注册路由
from django.urls import path, include from .views import BookView, PublishView # 导入类 from rest_framework.routers import SimpleRouter,DefaultRouter # 实例化得到对象 router = DefaultRouter() # 自动生成路由 router.register("books", BookView, "books") # 上面的自动映射命令等于下面两行映射代码 # path('books/', BookView.as_view({"get": "list", "post": "create"})), # path('books/<int:pk>/', BookView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})), router.register("publish", PublishView, "publish") # 继承ModelViewSet后路由就变了,需要映射 urlpatterns = [ # 把自动生成的路由,注册进总路由 # 方式一: path('', include(router.urls)), ] # 方式二: # urlpatterns和router.urls都是列表,这行代码将router.urls列表添加到urlpatterns列表中 urlpatterns += router.urls
【3】SimpleRouter和DefaultRouter区别
-
DefaultRouter不会直接报错,会生成一个根路径进行提示可前往的路由
【4】继承了ViewSetMixin ,视图类中可以定义跟请求方式不同名的方法
from rest_framework.viewsets import ModelViewSet, ViewSet from .models import Book, Publish from .serializer import BookSerializer, PublishSerializer from rest_framework.decorators import action class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 装饰器 # get请求 http://127.0.0.1:8000/api/v1/books/login/ @action(methods=['GET'], detail=False) def login(self, request): print("登录成功") return Response({"code": 200, 'msg': "登录成功"}) class PublishView(ViewSet): queryset = Publish.objects.all() serializer_class = PublishSerializer # 使用get请求 http://127.0.0.1:8000/api/v1/publish/send_sms/ @action(methods=['GET'], detail=False) def send_sms(self, request): print("发送短信成功") return Response({"code": 200, 'msg': "发送短信成功"})
【5】action参数
methods=请求方式,可以有多个, detail=False或True, False: api/v1/books/login/ True: api/v1/books/4/login/ 会带pk值 用的少 url_path=None # 路径名字,不写默认以方法名,如果 url_path=aa ---》api/v1/books/aa/ url_name=None # 反向解析用,不用了
【6】在视图类对象中,有action参数,就是方法名的字符串
from rest_framework.viewsets import ModelViewSet, ViewSet from .models import Book, Publish from .serializer import BookSerializer, PublishSerializer from rest_framework.decorators import action class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer def get_serializer_class(self): if self.action == 'list' or self.action == 'create': return BookSerializer elif self.action == 'retrieve' or self.action == 'destroy' or self.action == 'update': return PublishSerializer elif self.action == "login": return BookSerializer # 装饰器 # get请求 http://127.0.0.1:8000/api/v1/books/login/ @action(methods=['GET'], detail=False) def login(self, request): print("登录成功") return Response({"code": 200, 'msg': "登录成功"})