1.1 首先明确封装,因为不同的增删改查的区别就在于 表 不同,序列化器 不同,
表 和 序列化类可以写一个类方法里面
1.2 单条查询和多条查询不一样,分开写
1.3 所以策略是:
-- 先写一个基类,定义空的 queryset 和 serializers 用来被继承后重写,
-- 单条的再写单独的类
1.4 注意返回 queryset 的时候加上 .all() 方法
1.5 注意返回序列化函数的时候设置参数 *args,**kwargs
1.6 命名规范
--GenericAPIView 用于被继承重写,关键词 Generic
--XxxModelMixin 单独继承无意义,关键词 ModelMixin
from rest_framework.viewsets import ViewSetMixin
from DjangoDemo.models import Book
from rest_framework.views import APIView, Response
from SerDemo.serializers import BookSerializer
from rest_framework import views
"""""""""""""""全局第一次&第二次封装"""""""""""""""
class GenericAPIView(APIView):
"""
Generic
第一次封装
step1: 父类参数不同,定义为None,让子类重写
"""
queryset = None
serializers_class = None
# 定制函数返回queryset
def get_queryset(self):
return self.queryset.all() # django 的坑
# 定制函数返回序列化类
def get_serializers(self, *args, **kwargs):
return self.serializers_class(*args, **kwargs)
# 展示逻辑
class ListModelMixin(GenericAPIView): # Mixin
def list(self, request):
queryset = self.get_queryset()
ser_obj = self.get_serializers(queryset, many=True)
return Response(ser_obj.data)
# 创建逻辑
class CreateModelMixin(GenericAPIView):
def create(self, request):
ser_obj = self.get_serializers(data=request.data)
if ser_obj.is_valid():
ser_obj.save()
return Response(ser_obj.validated_data)
else:
return Response(ser_obj.errors)
# 第二次封装只是方便继承
class ListCreateAPIView(ListModelMixin, CreateModelMixin):
pass
# 对某一批书籍查询&新建书籍
class BookView(ListCreateAPIView):
"""
step2: 继承类并对参数重写
子类将用够父类的全部方法
"""
queryset = Book.objects.all()
serializers_class = BookSerializer
# def get(self, request):
# # 调用外部的get方法
# book_queryset = Book.objects.all()
# # 用序列化器进行序列化
# ser_obj = BookSerializer(book_queryset, many=True)
# return Response(ser_obj.data)
# 增加图书的视图
# post验证反序列化的校验
# 注意save
def get(self, request):
return self.list(request)
# def post(self, request):
# # 接口传过来的data在request.data里面
# # 用序列化器对post参数进行字段的额校验
# ser_obj = BookSerializer(data=request.data)
# if ser_obj.is_valid():
# ser_obj.save()
# return Response(ser_obj.validated_data)
# else:
# return Response(ser_obj.errors)
def post(self, request):
return self.create(request)
"""""""""""""""多条&单条分割线"""""""""""""""
# 查看单条类
class RetrieveModelMixin(GenericAPIView):
def retrieve(self, request, pk):
book_obj = self.get_queryset().filter(id=pk).first()
ser_obj = self.get_serializers(book_obj)
return Response(ser_obj.data)
# 更新单条类
class UpdateModelMixin(GenericAPIView):
def update(self, request, pk):
book_obj = self.get_queryset().filter(id=pk).first()
ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
if ser_obj.is_valid():
ser_obj.save()
return Response('校验之后的数据是-->{}'.format(ser_obj.validated_data))
return Response('校验失败,失败信息-->{}'.format(ser_obj.errors))
# 删除单条类
class DestroyModelMixin(GenericAPIView):
def destroy(self, request, pk):
book_obj = self.get_queryset().filter(id=pk).first()
if not book_obj:
return Response('删除书籍不存在')
book_obj.delete()
return Response('书籍删除成功!')
# 第二次封装只是方便继承
class RetrieveUpdateDestroyAPIView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
pass
# 对某一条数据查询和编辑
class BookEditView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
queryset = Book.objects.all()
serializers_class = BookSerializer
# def get(self, request, obj_id):
# book_obj = Book.objects.filter(id=obj_id).first()
# ser_obj = BookSerializer(book_obj)
# return Response(ser_obj.data)
def get(self, request, pk):
return self.retrieve(request, pk)
# def put(self, request, obj_id):
# book_obj = Book.objects.filter(id=obj_id).first()
# "put请求进行编辑"
# "instance对象,data数据,partial参数"
# ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
# if ser_obj.is_valid():
# ser_obj.save()
# return Response('校验之后的数据是-->{}'.format(ser_obj.validated_data))
# return Response('校验失败,失败信息-->{}'.format(ser_obj.errors))
def put(self, request, pk):
return self.update(request, pk)
# def delete(self, request, obj_id):
# book_obj = Book.objects.filter(id=obj_id).first()
# if not book_obj:
# return Response('删除书籍不存在')
# book_obj.delete()
# return Response('书籍删除成功!')
def delete(self, request, pk):
return self.destroy(request, pk)
2.1.1 写一个类继承所有的二次封装类
2.1.2 再继承一个 ViewSetMixin 类,from rest_framework.viewsets import ViewSetMixin
2.1.3 写一个类继承这个三次封装的类,同样配置 queryset 和 serializer_class
"""""""""""""""全局第三次封装"""""""""""""""""
# 继承 ViewSetMixin(from rest_framework.viewsets import ViewSetMixin) 和 上面第二次只继承的 pass 类
class ModelViewSet(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView):
pass
# 对全局APIView进行第三次封装
class BookModelView(ModelViewSet):
# 同样配置 queryset 和 serializer_class
queryset = Book.objects.all()
serializers_class = BookSerializer
2.2.1 将views里面写的第三次封装的BookModelView拿过来 2.2.2 大坑!id全部使用 pk 来代替 2.2.3 参数接受一个字典,键值分别是 请求方式:处理逻辑的函数名
"""将views里面写的第三次封装的BookModelView拿过来"""
"""大坑!id全部使用 pk 来代替"""
"""参数接受一个字典,键值分别是 请求方式:处理逻辑的函数名 """
urlpatterns = [
url(r'book/$', views.BookModelView.as_view({"get": "list", "post": "create"})),
url(r'book/(?P<pk>\d+)', views.BookModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
]
# 帮助我们生成带参数的路由
from rest_framework.routers import DefaultRouter
# 实例化DefaultRouter对象
router = DefaultRouter()
# 注册我们的路由以及视图
router.register(r'^book', views.BookModelView)
# urlpatterns += router.urls
class MyVersion(object):
@staticmethod
# 固定函数名称,在请求到达视图之前对版本进行控制
def determine_version(request, *args, **kwargs):
# 方法的返回值是版本号
# 获取前端传过来的版本号 并且把版本号返回
version = request.query_params.get("version")
if not version:
version = "v1"
return version
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [],
# 对版本控制类配置
"DEFAULT_VERSIONING_CLASS": "utils.version.MyVersion",
# 默认版本
'DEFAULT_VERSION': None,
# 允许的版本
'ALLOWED_VERSIONS': None,
'VERSION_PARAM': 'version'
}
# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView
class VersionDemo(APIView):
# 这里也可以对单独的某个视图请求配置版本
# versioning_class = MyVersion
def get(self, request):
print('当前版本-->', request.version)
# scheme我配置的版本控制类的实例化对象
print(request.versioning_scheme)
return Response('版本控制接口')
# 进入 versioning
from rest_framework import versioning
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。