翼度科技»论坛 编程开发 python 查看内容

两个视图基类 快速实现publish的5个接口 9个视图子类

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
1 两个视图基类
  1. # APIView--->之前一直在用---》drf提供的最顶层的父类---》以后所有视图类,都继承自它
  2. # GenericAPIView--》继承自APIView--》封装
复制代码
1.1 继承APIView+序列化类+Response写接口

urls.py--子路由--app01--urls.py
  1. from django.contrib import admin
  2. from django.urls import path,include
  3. from app01 import views
  4. urlpatterns = [
  5.     path('books/',views.BookView.as_view()),
  6.     path('books/<int:pk>/',views.BookDetaiView.as_view())
  7. ]
复制代码
序列化类
  1. serializer.py
  2. from rest_framework import serializers
  3. from .models import Book
  4. class BookSerializer(serializers.ModelSerializer):
  5.     class Meta:
  6.         model=Book
  7.         # 'publish', 'authors'反序列化
  8.         fields=['id','name','price','publish','authors','author_list','publish_detail']
  9.         extra_kwars={
  10.             'publish':{'weite_only':True},
  11.             'authors':{'weite_only':True},
  12.             'author_list':{'read_only':True},
  13.             'publish_detail':{'read_only':True},
  14.         }
复制代码
表模型
  1. from django.db import models
  2. # Create your models here.
  3. from django.db import models
  4. class Book(models.Model):
  5.     name = models.CharField(max_length=32)
  6.     price = models.DecimalField(max_digits=5, decimal_places=2)
  7.     publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
  8.     authors = models.ManyToManyField(to='Author')
  9.     @property
  10.     def publish_detail(self):
  11.         return {'name': self.publish.name, 'city': self.publish.city}
  12.     @property
  13.     def author_list(self):
  14.         l = []
  15.         for author in self.authors.all():
  16.             l.append({'name': author.name, 'age': author.age})
  17.         return l
  18.     def __str__(self):
  19.         return self.name
  20. class Author(models.Model):
  21.     name = models.CharField(max_length=32)
  22.     age = models.IntegerField()
  23.     author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
  24.     def __str__(self):
  25.         return self.name
  26. class AuthorDetail(models.Model):
  27.     telephone = models.BigIntegerField()
  28.     birthday = models.DateField()
  29.     addr = models.CharField(max_length=64)
  30. class Publish(models.Model):
  31.     name = models.CharField(max_length=32)
  32.     city = models.CharField(max_length=32)
  33.     email = models.EmailField()
  34.     def __str__(self):
  35.         return self.name
  36.     class Meta:
  37.         verbose_name = '出版社'
  38.         verbose_name_plural = verbose_name
复制代码
视图类
  1. from .serializer import BookSerializer
  2. from rest_framework.views import APIView
  3. from rest_framework.generics import GenericAPIView
  4. from .models import Book
  5. from rest_framework.response import Response
  6. class BookView(APIView):
  7.     def get(self, request):
  8.         booklist = Book.objects.all()
  9.         ser = BookSerializer(instance=booklist, many=True)
  10.         return Response(ser.data)
  11.     def post(self, request):
  12.         ser = BookSerializer(data=request.data)
  13.         if ser.is_valid():
  14.             ser.save()
  15.             return Response(ser.data)
  16.         else:
  17.             return Response(ser.errors)
  18. class BookDetaiView(APIView):
  19.     def put(self, request, *args, **kwargs):
  20.         book = Book.objects.filter(pk=kwargs.get('pk')).first()
  21.         ser = BookSerializer(instance=book, data=request.data)
  22.         if ser.is_valid():
  23.             ser.save()
  24.             return Response(ser.data)
  25.         else:
  26.             return Response(ser.errors)
  27.     def get(self, request, *args, **kwargs):
  28.         book = Book.objects.filter(pk=kwargs.get('pk')).first()
  29.         ser = BookSerializer(instance=book)
  30.         return Response(ser.data)
  31.     def delete(self, request, *args, **kwargs):
  32.         Book.objects.filter(pk=kwargs.get('pk')).first()
  33.         return Response('')
复制代码
1.2 继承GenericAPIView+序列化类+Response写接口
  1. #第二层继承GenericAPIView+序列化类+Response写接口
  2. from rest_framework.generics import GenericAPIView
  3. class BookView(GenericAPIView):
  4.     # 先配置两个类属性
  5. #用的话必须写
  6.     queryset =Book.objects.all()
  7.     serializer_class = BookSerializer
  8.     def get(self, request):
  9.         object_list = self.get_queryset()#获取所有要序列化的数据
  10.         ser = self.get_serializer(instance=object_list, many=True)#获取序列化类
  11.         return Response(ser.data)
  12.     def post(self, request):
  13.         ser = self.get_serializer(data=request.data)
  14.         if ser.is_valid():
  15.             ser.save()
  16.             return Response(ser.data)
  17.         else:
  18.             return Response(ser.errors)
  19. class BookDetaiView(GenericAPIView):
  20.     # 先配置两个类属性
  21.     queryset = Book.objects.all()
  22.     serializer_class = BookSerializer
  23.     def put(self, request, *args, **kwargs):
  24.         # book = Book.objects.filter(pk=kwargs.get('pk')).first()
  25.         obj=self.get_object()#获取单条数据--》内部就是按pk从request中获取,取除pk对应的值,查询
  26.         ser = self.get_serializer(instance=obj, data=request.data)
  27.         if ser.is_valid():
  28.             ser.save()
  29.             return Response(ser.data)
  30.         else:
  31.             return Response(ser.errors)
  32.     def get(self, request, *args, **kwargs):
  33.         # book = Book.objects.filter(pk=kwargs.get('pk')).first()
  34.         obj=self.get_object()
  35.         ser = self.get_serializer(instance=obj)
  36.         return Response(ser.data)
  37.     def delete(self, request, *args, **kwargs):
  38.         # Book.objects.filter(pk=kwargs.get('pk')).first()
  39.         self.get_object().delete()
  40.         return Response('')
复制代码
快速实现publish的5个接口

只需要修改视图类上的两个类属性即可,其他的不用动
urls.py
  1. from django.contrib import admin
  2. from django.urls import path,include
  3. from app01 import views
  4. urlpatterns = [
  5.     #path('books/',views.BookView.as_view()),
  6.     #path('books/<int:pk>/',views.BookDetaiView.as_view()),
  7.     path('publish/',views.PublishView.as_view()),
  8.     path('publish/<int:pk>/',views.PublishDetaiView.as_view())
  9. ]
复制代码
views.py
  1. #快速实现publish的5个接口
  2. from .models import Publish
  3. from .serializer import PublishSerializer
  4. class PublishView(GenericAPIView):
  5.     # 先配置两个类属性
  6. #用的话必须写
  7.     queryset =Publish.objects.all()
  8.     serializer_class = PublishSerializer
  9.     def get(self, request):
  10.         # object_list = self.queryset.all()  # 获取所有要序列化的数据
  11.         #         #1 写成方法的目的--》调用all()
  12.         #         #2 子类可以重写这个方法--》返回什么,待序列化的数据就是什么
  13.         #         object_list = self.get_queryset()  # 获取所有要序列化的数据
  14.         object_list = self.get_queryset()#获取所有要序列化的数据
  15.         ser = self.get_serializer(instance=object_list, many=True)#获取序列化类
  16.         # 本质就是---》 self.serializer_class(instance=object_list, many=True)
  17.         return Response(ser.data)
  18.     def post(self, request):
  19.         ser = self.get_serializer(data=request.data)
  20.         if ser.is_valid():
  21.             ser.save()
  22.             return Response(ser.data)
  23.         else:
  24.             return Response(ser.errors)
  25. class PublishDetaiView(GenericAPIView):
  26.     # 先配置两个类属性
  27.     queryset = Publish.objects.all()
  28.     serializer_class = PublishSerializer
  29.     def put(self, request, *args, **kwargs):
  30.         # book = Book.objects.filter(pk=kwargs.get('pk')).first()
  31.         obj=self.get_object()#获取单条数据--》内部就是按pk从request中获取,取除pk对应的值,查询
  32.         ser = self.get_serializer(instance=obj, data=request.data)
  33.         if ser.is_valid():
  34.             ser.save()
  35.             return Response(ser.data)
  36.         else:
  37.             return Response(ser.errors)
  38.     def get(self, request, *args, **kwargs):
  39.         # book = Book.objects.filter(pk=kwargs.get('pk')).first()
  40.         obj=self.get_object()
  41.         ser = self.get_serializer(instance=obj)
  42.         return Response(ser.data)
  43.     def delete(self, request, *args, **kwargs):
  44.         # Book.objects.filter(pk=kwargs.get('pk')).first()
  45.         self.get_object().delete()
  46.         return Response('')
复制代码
serializer.py
  1. class PublishSerializer(serializers.ModelSerializer):
  2.     class Meta:
  3.         model = Publish
  4.         fields = "__all__"
复制代码
继承GenericAPIView的写法
  1.         -1 在类中,写两个类属性:所有数据,序列化类
  2.         queryset = Book.objects.all()
  3.             serializer_class = BookSerializer
  4.     -2 获取所有要序列化的数据
  5.             self.get_queryset()
  6.     -3 获取序列化类
  7.             self.get_serializer(参数跟之前一样)
  8.     -4 获取单挑
  9.             self.get_object()
复制代码
GenericAPIView源码分析
  1. -1 继承了APIView
  2. -2 有些类属性--》目前只记住两个queryset,serializer_class
  3.         queryset        # 要序列化的所有数据
  4.     serializer_class  # 序列化类
  5.     lookup_field = 'pk' # 查询单条,前端传入的参数对应值【pk】,转换器
  6.     filter_backends  # 后续要学的,过滤
  7.     pagination_class # 后续要学的,分页
  8.    
  9.    
  10.    
  11.   -3 有些对象方法
  12.            -get_queryset: 返回待序列化的数据
  13.                     1 调用 .all
  14.                 2 在子类中重写,控制要序列化的数据
  15.        -get_serializer: 返回 序列化类  以后用它
  16.                     -本质就是---》 self.serializer_class(instance=object_list, many=True)
  17.              -内部调用了:self.get_serializer_class
  18.              -后期在子类中重写get_serializer_class,返回什么序列化类,以后就以哪个序列化类做序列化
  19.               
  20.                
  21.        - get_serializer_class 它是用来重写的
  22.         def get_serializer_class(self):
  23.             if self.request.method=='GET':
  24.                 return '序列化的类'
  25.             else:
  26.                 return '反序列化的类'
  27.             
  28.       -get_object 获取单条---》根据它:lookup_field   获取
  29.            
复制代码
第三层:继承 GenericAPIView+5个视图扩展类+序列化类+Response

5个视图扩展类(不是视图类--》没有继承APIView及其子类,不能单独用,需要配合GenericAPIView)---》每个分别写的5个接口中得某一个方法
  1. from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, \
  2.     DestroyModelMixin
  3.    
  4.     #CreateModelMixin 新增
  5. #ListModelMixin  查询所有
  6. #RetrieveModelMixin  查询单条
  7. #UpdateModelMixin  修改
  8. # DestroyModelMixin  销毁
复制代码
views.py
  1. from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, \
  2.     DestroyModelMixin
  3. class BookView(GenericAPIView,CreateModelMixin,ListModelMixin):
  4.     # 先配置两个类属性
  5. #用的话必须写
  6.     queryset =Book.objects.all()
  7.     serializer_class = BookSerializer
  8.     def get(self, request):
  9.         # object_list = self.get_queryset()#获取所有要序列化的数据
  10.         # ser = self.get_serializer(instance=object_list, many=True)#获取序列化类
  11.         # return Response(ser.data)
  12.         return super().list(request)
  13.     def post(self, request):
  14. # 做保存,加了这一句---》目的是:子类可以重写,增强扩展性
  15. # self.perform_create(serializer)
  16.         return super().list(request)
  17. class BookDetailView(GenericAPIView, RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin):
  18.     queryset = Book.objects.all()
  19.     serializer_class = BookSerializer
  20.     def put(self, request, *args, **kwargs):
  21.         return super().update(request, *args, **kwargs)
  22.     def get(self, request, *args, **kwargs):
  23.         return super().retrieve(request, *args, **kwargs)
  24.     def delete(self, request, *args, **kwargs):
  25.         return super().destroy(request, *args, **kwargs)
复制代码
9个视图子类

第四层:9个视图子类---》视图类
  1. #CreateModelMixin 新增
  2. #ListModelMixin  查询所有
  3. # ListCreateAPIView 新增+查询所有
  4. #RetrieveModelMixin  查询单条
  5. #UpdateModelMixin  修改
  6. # DestroyModelMixin  销毁
  7. # RetrieveUpdateDestroyAPIView  查询单条+修改+销毁
  8. # RetrieveDestroyAPIView  查询单条+ 销毁
  9. # RetrieveUpdateAPIView查询单条+修改
  10. # CreateAPIView继承了 GenericAPIView, CreateModelMixin,写了post方法
  11. from rest_framework.generics import CreateAPIView,ListAPIView,ListCreateAPIView
  12. from rest_framework.generics import RetrieveAPIView,DestroyAPIView,UpdateAPIView,RetrieveUpdateDestroyAPIView
  13. from rest_framework.generics import RetrieveDestroyAPIView,RetrieveUpdateAPIView
  14. #实现
  15. class BookView(ListCreateAPIView):
  16.     # 先配置两个类属性
  17. #用的话必须写
  18.     queryset =Book.objects.all()
  19.     serializer_class = BookSerializer
  20.    
  21.    
  22. class BookDetailView(RetrieveUpdateDestroyAPIView):
  23.     queryset = Book.objects.all()
  24.     serializer_class = BookSerializer
  25.    
  26.     # 实现新增,查所有和查询一条
  27. # class BookView(ListCreateAPIView):
  28. #     # 配置两个类属性
  29. #     queryset = Book.objects.all()
  30. #     serializer_class = BookSerializer
  31. #
  32. #
  33. # class BookDetailView(RetrieveAPIView):
  34. #     queryset = Book.objects.all()
  35. #     serializer_class = BookSerializer
复制代码
来源:https://www.cnblogs.com/zhangfanshixiaobai/p/17927061.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具