2个视图基类、5 个视图扩展类、9个视图子类、视图集、路由组件
2个视图基类#
# django 内置的View
# drf 的APIView ,继承自View
# GenericAPIView
--两个重要的类属性:
-queryset = Book.objects.all() # 要序列化的数据
-serializer_class = BookSerializer # 序列化类
--几个重要的方法:
-self.get_queryset() # 得到查询结果集
-self.get_serializer(instance=book_list, )
'''
指定了查询结果集,就代表数据已经定了,接下来都是在这个查询结果集里面进行对数据库的增删查改了。
要使用序列化器,直接 self.get_serializer()调用。
'''
-self.get_object() # 得到单独的一个对象
'''
调用了self.get_object(),谁调用他,他就会先从那个调用他的函数中获取到名为pk的值,再将名为pk的值作为id条件,在查询结果集中进行匹配,匹配成功,将对象返回出来。
'''
使用APIView写5个接口#
class BookView(APIView):
def get(self,request):
book_list=Book.objects.all()
# 如果写了many=True,ser是哪个类的对象?
ser=BookSerializer(instance=book_list,many=True)
print(type(ser)) # ListSerializer的对象---》[BookSerializer,BookSerializer,BookSerializer]
return Response(ser.data)
def post(self,request):
ser=BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':'100','msg':'创建成功'})
else:
return Response({'code': '101', 'msg': '创建失败','err':ser.errors})
class BookDetailView(APIView):
def get(self,request,*args,**kwargs): # pk 从kwargs中去
book=Book.objects.filter(pk=kwargs['pk']).first()
# 如果写了many=True,ser是哪个类的对象?
ser=BookSerializer(instance=book)
print(type(ser)) # BookSerializer的对象
return Response(ser.data)
#put:全局修改 patch:局部修改
def put(self,request,*args,**kwargs): # pk 从kwargs中去
book=Book.objects.filter(pk=kwargs['pk']).first()
ser=BookSerializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': '100', 'msg': '创建成功'})
else:
return Response({'code': '101', 'msg': '创建失败', 'err': ser.errors})
继承GenericAPIView写5个接口#
'重点'
-使用的方法属性
-queryset = Book.objects.all() # 要序列化的数据
-serializer_class = BookSerializer # 序列化类
-继承父类
GenericAPIView
class BookView(GenericAPIView):
queryset = Book.objects.all() # 要序列化的数据
serializer_class = BookSerializer # 序列化类
def get(self, request):
print('dsafdasdfasd')
book_list = self.get_queryset() # 获取要序列化的数据,不要直接使用self.queryset,而要用self.get_queryset()
# 获取序列化类,要使用self.get_serializer
ser = self.get_serializer(instance=book_list, many=True)
print(type(ser)) # ListSerializer的对象---》[BookSerializer,BookSerializer,BookSerializer]
return Response(ser.data)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': '100', 'msg': '创建成功'})
else:
return Response({'code': '101', 'msg': '创建失败', 'err': ser.errors})
class BookDetailView(GenericAPIView):
queryset = Book.objects.all() # 要序列化的数据
serializer_class = BookSerializer # 序列化类
#传入的必须叫pk,否则,get_object就拿不到对象
def get(self, request, *args, **kwargs):
# 获取单个对象,
book = self.get_object()
# 如果写了many=True,ser是哪个类的对象?
ser = self.get_serializer(instance=book)
print(type(ser)) # BookSerializer的对象
return Response(ser.data)
# put:全局修改 patch:局部修改
def put(self, request, *args, **kwargs): # pk 从kwargs中去
book = self.get_object()
ser = self.get_serializer(instance=book, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': '100', 'msg': '创建成功'})
else:
return Response({'code': '101', 'msg': '创建失败', 'err': ser.errors})
5 个视图扩展类#
# 视图扩展类---》不是视图类---》没有继承视图类(View,APIView...子类)
ListModelMixin # 获取所有
CreateModelMixin # 创建一个
RetrieveModelMixin # 查询一个
UpdateModelMixin # 更新一个
DestroyModelMixin # 删除一个
-需要搭配GenericAPIView使用
eg:class Books(GenericAPIView, ListModelMixin, CreateModelMixin):
使用5个视图扩展类写五个接口#
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
class BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
queryset = Book.objects.all() # 要序列化的数据
serializer_class = BookSerializer # 序列化类
def get(self,request):
print('获取所有')
return super().list(request)
def post(self, request):
return super().create(request)
class BookDetailView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
queryset = Book.objects.all() # 要序列化的数据
serializer_class = BookSerializer # 序列化类
#传入的必须叫pk,否则,get_object就拿不到对象
def get(self, request, *args, **kwargs):
print('获取一')
return super().retrieve(request, *args, **kwargs)
# put:全局修改 patch:局部修改
def put(self, request, *args, **kwargs): # pk 从kwargs中去
return super().update(request, *args, **kwargs)
def delete(self,request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)
9个视图子类#
'''9个视图子类'''
'''
ListAPIView 获取所有
CreateAPIView 新增一个
-ListCreateAPIView 获取所有和新建一个
RetrieveAPIView 获取单个
UpdateAPIView 更新一个
DestroyAPIView 删除一个
-RetrieveUpdateDestroyAPIView 获取单个更新一个删除一个
-RetrieveUpdateAPIView 获取和更新
-RetrieveDestroyAPIView 获取一个和删除一个
使用9个视图子类写五个接口#
继承9个视图子类后,只需要在视图类中写两个类属性即可
class BookView(ListCreateAPIView): # 获取所有和新增一个
queryset = Book.objects.all() # 要序列化的数据
serializer_class = BookSerializer # 序列化类
class BookDetailView(RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all() # 要序列化的数据
serializer_class = BookSerializer # 序列化类
视图集#
# 视图集中的类
-ModelViewSet
-ReadOnlyModelViewSet
-ViewSetMixin
-ViewSet:ViewSetMixin+APIView
-GenericViewSet:ViewSetMixin+GenericAPIView
# 以后你想继承APIView,但是路由想自动生成,继承ViewSet
# 以后想继承GenericAPIView,但是路由想自动生成,GenericViewSet
ModelViewSet#
ModelViewSet是封装度最高
的DRF的视图类。包含了增删改查中的所有接口操作。
它继承
自GenericViewSet、ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
class UserView(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
自定义action#
def 名称(self, request):
'''
自定义action
:return: JSON数据
'''
pass
路由代码#
path('user/', views.UserView.as_view({'post': 'action名称'})),
案例代码#
class UserView(ModelViewSet):
# @action(methods=['POST', ], detail=False, url_path='login', url_name='login')
def login(self, request):
user = User.objects.all()
ser = UserSerializer(instance=user, data=request.data)
if ser.is_valid():
return Response({'msg': '登录成功'})
else:
return Response({'msg': '登录失败', 'err': ser.errors})
# 路由代码
path('user/', views.UserView.as_view({'post': 'login'})),
ReadOnlyModelViewSet#
-
继承了
mixins.RetrieveModelMixin, mixins.ListModelMixin, GenericViewSet
此方法提供了get请求多条与单条数据的方法
ViewSetMixin#
需要搭配APIView一起使用
# ViewSetMixin 写在前面,先找ViewSetMixin的as_view方法
# 用了ViewSetMixin ,视图类中,不需要再写get,post,delete....这些函数了,函数名可以自定义
# 而且这个视图类,可以响应多条路由
ViewSet#
包含了ViewSetMixin+APIView
GenericViewSet#
包含了ViewSetMixin+GenericAPIView
总结#
# 以后你想继承APIView,但是路由想自动生成,继承ViewSet
# 以后想继承GenericAPIView,但是路由想自动生成,GenericViewSet
路由组件#
路由写法#
# 1 继承了ViewSetMixin及其子类,路由写法变了
-写法一:path('publish', views.PublishView.as_view({'get': 'lqz','post':'login'})),
-写法二:自动生成
# 第一步:导入一个路由类
from rest_framework.routers import SimpleRouter, DefaultRouter
# 第二步:实例化得到对象
router=SimpleRouter()
# router = DefaultRouter() # 它会给每个注册的视图类都生成一个根路由
# 第三步:注册路由---》使用视图类注册---》能自动生成路由
router.register('books', views.BookView, 'books')
router.register('publish', views.BookView, 'publish')
# 第四步:在总路由中注册 方式二
path('', include(router.urls)),
# 第四步:在总路由中注册 方式一
# urlpatterns+=router.urls
action装饰器的用法#
-之前自动生成路由只能生成
{'get': 'list', 'post': 'create'},{'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}
-使用action装饰器来做对应关系
path('user/', views.UserView.as_view({'post': 'login'})),
@action(methods=['POST', ], detail=False, url_path='login', url_name='login')
'''
methods:请求方式
detail:
False:是不带id的路由 http://127.0.0.1/publish/3
http://127.0.0.1/publish
True: 生成的路由publish/pk/lqz/
url_path:如果不写,就是函数名生成的路径是:http://127.0.0.1/publish/lqz
url_name:别名
'''
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人