两个视图基类
# 基于 GenericAPIView
"""
几个方法:
queryset = Publish.objects.all() #获取所有数据
serializer_class = PublishSerializer # 指定的序列化类
self.get_queryset() # 获取所有要序列化的数据
get_serializer(instance=object_list, many=True) # 获取序列化类
get_object() # 获取单条---》内部就是按pk从request中取,取出pk对应的值,查询的
"""
class BookGenericAPIView(GenericAPIView):
queryset = models.Book.objects.all() # 对应的是查询出来的数据
serializer_class = Myserializer # 指定的序列化类
def get(self, request): # 查询所有
object_list = self.get_queryset() # 一定要加上括号
# 序列化的参数和 APIView 一样的
ser = self.get_serializer(instance=object_list,many=True)
return Response({'code':100,'msg':'查询所有成功','result':ser.data})
def post(self,request):
# 序列化类 跟APIView 大差不多的
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '添加成功', 'result': ser.data})
return Response({'code': 101, 'msg': '添加失败'})
class BookGenericAPIView_pk(GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = Myserializer # 不需要加括号
def get(self,request,*args,**kwargs):
book = self.get_object()
ser = self.get_serializer(book)
return Response({'code':100,'msg':'查询一条成功','result':ser.data})
def put(self,request,*args,**kwargs):
book = self.get_object() # 获取单条---》内部就是按pk从request中取,取出pk对应的值,查询的
ser = self.get_serializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
return Response({'code': 101, 'msg': '修改失败'})
def delete(self,*args,**kwargs):
self.queryset.filter(id=kwargs.get('pk')).first().delete()
return Response({'code': 100, 'msg': '删除成功'})
# 序列化类
class Myserializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
# 模型层
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish = models.CharField(max_length=16)
addr = models.CharField(max_length=16)
# 路由
urlpatterns = [
path('BookGenericAPIView_pk/<int:pk>',views.BookGenericAPIView_pk.as_view()),
path('BookGenericAPIView/',views.BookGenericAPIView.as_view()),
path('BookAPIView_id/<int:pk>',views.BookAPIView_id.as_view()),
path('BookAPIView/',views.BookAPIView.as_view()),
]
# 基于APIView 写五个接口 两种的区别
class BookAPIView(APIView):
def get(self,request):
book = models.Book.objects.all()
book_serializer = Myserializer(instance=book,many=True)
return Response({'code':100,'msg':'查询所有成功','result':book_serializer.data})
def post(self,request):
create_serializer = Myserializer(data=request.data)
if create_serializer.is_valid():
create_serializer.save()
return Response({'code': 100, 'msg': '成功', 'result': create_serializer.data})
return Response({'code': 101, 'msg': '添加失败'})
class BookAPIView_id(APIView):
def get(self,request,pk):
book = models.Book.objects.filter(id=pk).first()
serializer_pk = Myserializer(instance=book)
return Response({'code': 100, 'msg': '查询一条成功', 'result': serializer_pk.data})
def put(self,request,pk):
book = models.Book.objects.filter(id=pk).first()
serializer = Myserializer(instance=book,data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'code': 100, 'msg': '修改成功', 'result': serializer.data})
return Response({'code': 101, 'msg': '修改失败'})
def delete(self, request,pk):
models.Book.objects.filter(id=pk).first()
return Response({'code': 100, 'msg': '删除成功'})
# 模型层 和 序列化类跟上面的一样的
总结
#两个基类
APIView:如果跟models没有关系(没有数据库相关操作),就继承它
GenericAPIView:有关数据库操作,queryset 和serializer_class
五个视图扩展类
视图扩展类必须跟 GenericAPIView 两个都要继承一起使用
# from rest_framework.mixins import 从这里导入
"""
ListModelMixin 里面有 list() 方法 相当于是get请求
RetrieveModelMixin 查看一条数据 也是 get 请求
CreateModelMixin 里面有 create方法 是post请求
DestroyModelMixin 里面有 destroy 方法 相当于是 delete 请求
UpdateModelMixin 里面有 updata方法 相当于是 put 请求
"""
# 基于五个视图扩展类写五个接口
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, \
UpdateModelMixin
class EveryoneGenericAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = models.Book.objects.all()
serializer_class = Myserializer
def get(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return super().create(request, *args, **kwargs)
class EveryoneGenericAPIView_pk(GenericAPIView, RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin):
queryset = models.Book.objects.all()
serializer_class = Myserializer
def get(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)
# 路由:
from django.urls import path
from app03 import views
urlpatterns = [
# 路由 转换 必须有pk 否则需要在视图类中重新配置
path('EveryoneGenericAPIView/',views.EveryoneGenericAPIView.as_view()),
path('EveryoneGenericAPIView_pk/<int:pk>/',views.EveryoneGenericAPIView_pk.as_view()),
]
九个视图子类
from rest_framework.generics import CreateAPIView,RetrieveAPIView,DestroyAPIView,ListAPIView,UpdateAPIView
from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView,RetrieveUpdateAPIView
# 基于 9个视图子类写五个接口
class CreateListAPIview(ListCreateAPIView):
queryset = models.Book.objects.all()
serializer_class = Myserializer
class RetrieveUpdateDestroyAPIview(RetrieveUpdateDestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = Myserializer
"""
CreateAPIView 继承了 CreateModelMixin 重写了 create方法 和 post 请求
ListAPIView 继承了 ListModelMixin 重写了 list方法 和 get 请求
RetrieveAPIView 继承了 RetrieveModelMixin 重写了 retrieve 方法 和 get 请求
DestroyAPIView 继承了 DestroyModelMixin 重写了 destroy 方法 和 delete 请求
UpdateAPIView 继承了 UpdateModelMixin 重写了 update 方法 和 put 请求
ListCreateAPIView 继承了 ListModelMixin和CreateModelMixin 重写了 create方法 和 list方法 处理了 get请求 和 post请求
RetrieveUpdateDestroyAPIView 继承了 RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin 重写了retrieve方法 destroy方法 update方法 处理了 get请求 delete请求 put请求
RetrieveDestroyAPIView 继承了 RetrieveModelMixin,DestroyModelMixin 重写了 retrieve方法 delete方法 处理了 delete请求 get请求
RetrieveUpdateAPIView 继承了 RetrieveModelMixin UpdateModelMixin 重写了 update方法 retrieve方法 处理了 get请求 put请求
"""
# 路由:
from django.urls import path
from app03 import views
urlpatterns = [
path('CreateListAPIview/<int:pk>/',views.RetrieveUpdateDestroyAPIview.as_view()),
path('CreateListAPIview/',views.CreateListAPIview.as_view()),
]
视图集
"""
#视图集
# ModelViewSet:
继承mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet
只要继承了 ModelViewSet 就能拥有了 五个接口 但是 路由写法必须如下这样子写 path('ViewsetMixin/',views.ViewsetMixin.as_view({'get':'register','post':'login'})),
# GenericViewSet
继承了
ViewSetMixin,
generics.GenericAPIView
# GenericViewSet
继承了ViewSetMixin, 重写了as_view 只要继承了ViewSetMixin 视图类中方法可以随便写了 只要路由映射对应的请求方式即可
generics.GenericAPIView
# ViewSet: 继承ViewSetMixin和APIView 继承的时候 ViewSetMixin必须写在前面
# ReadOnlyModelViewSet: 只允许查数据
继承
RetrieveModelMixin,
ListModelMixin,
GenericViewSet
"""
from rest_framework.viewsets import ModelViewSet
class ViewsetMixin(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = Myserializer
def register(self,*args,**kwargs):
return super().list(*args,**kwargs)
def register2(self,*args,**kwargs):
return super().retrieve(*args,**kwargs)
def login(self,*args,**kwargs):
return Response('这里是登录功能')
# 路由
path('ViewsetMixin/',views.ViewsetMixin.as_view({'get':'register','put':'login','delete':'login','post':'register3',})),
path('ViewsetMixin/<int:pk>/',views.ViewsetMixin.as_view({'get':'register1'})),
drf-路由和视图
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
# 自定义函数指定请求方式
class ViewsetMixin(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = Myserializer
# 增加装饰器之后 自定义的视图方法可以自己指定请求方式了 methods=[] 允许某种方式 就添加进去
# detail=None, 只能写True或False,如果写了false就是不带pk的路径,如果写了True路径带pk
# False的情况: http://127.0.0.1:8080/api/v1/books/login/
# True 的情况: http://127.0.0.1:8080/api/v1/books/8/login/
@action(methods=['POST','GET'],detail=False,url_name=None) # url_name=None :别名,用做反向解析
def register(self,*args,**kwargs):
return super().list(*args,**kwargs)
@action(methods=['POST'], detail=False, url_name=None)
def login(self,*args,**kwargs):
return Response('这里是登录功能')
路由
from django.urls import path,include
from app03 import views
from rest_framework.routers import SimpleRouter
# 实例化得到一个对象
# 方式一 写法
router = SimpleRouter()
urlpatterns = [
path('/api/v1', include(router.urls)),
]
# 方式二写法
router = SimpleRouter()
urlpatterns = [
]
# 第一个是路由地址 第二个是视图类 第三个是起路由别名
# 注册
router.register('ViewsetMixin', views.ViewsetMixin, 'ViewsetMixin')
# 添加到路由中
urlpatterns += router.urls
# 总结:以后只要继承ViewSetMixin或者ModelViewSet,就可以使用SimpleRouter方式写路由