序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口

首页 / 新闻资讯 / 正文

First Vector Graphic
  • 序列化多表操作
  • 请求与相应
  • 视图组件

1、序列化多表操作

模型类 models.py中

# 新建django项目 # 创建表 模型类models.py中: from django.db import models  # 4张表 class Book(models.Model):     name = models.CharField(max_length=32)     price = models.DecimalField(max_digits=5, decimal_places=2)     publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)  # to='Publish' 自动关联publish表主键 // on_delete=models.CASCADE 级联删除     authors = models.ManyToManyField(to='Author')      def __str__(self):         return self.name      @property     def publish_detail(self):  # 定制字段         return {'name': self.publish.name, 'addr': self.publish.city}      @property     def author_list(self):  # 定制字段         l = []         # print(self.authors.all())         for author in self.authors.all():             # print(author.author_detail)             l.append({'name': author.name, 'age': author.age, 'addr': author.author_detail.addr})         return l           class Author(models.Model):     name = models.CharField(max_length=32)     age = models.IntegerField()     author_detail = models.OneToOneField(to='AuthorDatail', on_delete=models.CASCADE)     # OneToOneField 就是 ForeignKey + unique=True   class AuthorDatail(models.Model):     telephone = models.BigIntegerField()     addr = models.CharField(max_length=64)   class Publish(models.Model):     name = models.CharField(max_length=32)     city = models.CharField(max_length=32)     email = models.EmailField()           """ 在每个表中写入数据一一对应 第五个自动创建的关联表 也写入数据 """

序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口

创建序列化类 serializer.py

from .models import * from rest_framework import serializers   class BookSerializer(serializers.ModelSerializer):     class Meta:         model = Book         # fields = '__all__'         fields = ['id', 'name', 'price', 'authors', 'publish', 'publish_detail', 'author_list']          # 由于前端的publish与authors会显示为:id 所以需要定制序列化字段         # depth=1  # 等同于定制序列化的字段(2种方案) 但是尽量不要用,因为它是关联表一层全部取出来         # 定制序列化的字段(2种方案)选择表模型中: 显示出版社名、地址;作者名年龄地址         extra_kwargs = {             'publish': {'write_only': True},  # 原有的字段就不需要再显示             'authors': {'write_only': True},         }   class AuthorSerializer(serializers.ModelSerializer):     class Meta:         model = Author         fields = '__all__'   class AuthorDetailSerialzier(serializers.ModelSerializer):     class Meta:         model = AuthorDatail         fields = '__all__'   class PublishSerialzier(serializers.ModelSerializer):     class Meta:         model = Publish         fields = '__all__'

视图类 views.py中:

from .serializer import * from rest_framework.response import Response from rest_framework.views import APIView from app01.models import Book   class BookView(APIView):     # 查询所有图书     def get(self, request):         book_list = Book.objects.all()         ser = BookSerializer(instance=book_list, many=True)         return Response(ser.data)      # 新增图书数据     def post(self, request):         ser = BookSerializer(data=request.data)         if ser.is_valid():             ser.save()             return Response({"code": 100, 'msg': '新增成功', 'data': ser.data})         return Response({"code": 101, 'msg': '新增失败', 'err': ser.errors})   class BookDetailView(APIView):      # 查询单条数据     def get(self, request, pk):         book = Book.objects.all().filter(pk=pk).first()         ser = BookSerializer(instance=book)         return Response(ser.data)      # 修改数据     def put(self, request, pk):         book = Book.objects.all().filter(pk=pk).first()         ser = BookSerializer(instance=book, data=request.data)         if ser.is_valid():             ser.save()             return Response({"code": 100, 'msg': '修改成功', 'data': ser.data})         return Response({"code": 101, 'msg': '修改出错', 'err': ser.errors})      # 删除数据     def delete(self, request, pk):         Book.objects.filter(pk=pk).delete()         return Response({"code": 100, 'msg': '删除成功'})

路由 urls.py中:

from django.contrib import admin from django.urls import path  from app01 import views  urlpatterns = [     path('admin/', admin.site.urls),      path('books/', views.BookView.as_view()),     path('books/<int:pk>', views.BookView.as_view()), ]

序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口

2、请求与相应

2.1 请求

# 请求就是指:Request 类的对象 	>>> 新的request对象      # 导入: 	from rest_framework.request import Request  # 需要记住的源码: 	__getattr__ 	request.data 	request.query_parmas--->self._request.GET 		restful规范里,请求地址中带过滤(查询)条件 		get请求地址中提交的数据在GET中, 		query_parmas:查询参数                   # 了解 	默认情况下,可以解析 urlencoded,formdata,json           # 案例: 	如果我们写了一个接口,想只能处理json格式,或者只能处理formdata      1.局部配置 在views.py中: from rest_framework.parsers import JSONParser, FormParser, MultiPartParser  class PublishView(APIView):     # 局部使用,只针对当前视图类有效     # 只想处理json格式     # parser_classes = [JSONParser,FormParser,MultiPartParser]  # 默认下 是处理三种格式数据     parser_classes = [JSONParser]  # 只允许处理 JSONParser格式      def post(self, request):         print(request.data)         return Response('post---publish') 	    2.全局配置-->要在配置文件中添加: # REST_FRAMEWORK  以后是drf的配置 # 所有接口都只能解析json格式 REST_FRAMEWORK = {     'DEFAULT_PARSER_CLASSES': [         'rest_framework.parsers.JSONParser',     ], }  3.全局配置解析json,局部某个视图函数想能解析formdata格式 	视图类中配置一下即可 就是局部配置(按照使用顺序)           # 如果局部配置如下,会怎么样 	parser_classes = []  # 所有格式都补不能解析了  # 使用顺序: 	即使我们没有配置局部或者全局,也有默认配置:3个数据模式都能解析      	视图类中配的(优先用) 	项目配置文件的配置(其次) 	drf有默认配置(最后) 	 	drf的默认配置:from rest_framework import settings     # 总结: 	一般情况下,都使用默认即可,不用配置(三种格式数据都能解析)

序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口

2.2 响应

# 其实就是:Respone 返回给前端的  # 导入: 	from rest_framework.response import Response      # 源码分析 1.属性: 	data=None,  # 返回给前端的数据:可以是 字符串,字典,列表 就是给http响应body体中内容-->也可以是response对象中取出数据并 处理      	status=None,  # 响应状态码:1xx,2xx,3xx,默认是200  	headers=None,      # 响应头 字典    	了解: 		template_name=None,  # 模板名字(不用),用浏览器访问时,可以改 		exception=False,    # 异常处理 		content_type=None   # 响应编码格式               	from rest_framework.status import HTTP_201_CREATED 	Response(ser.data,status=HTTP_201_CREATED)      2.响应格式 跟解析数据格式类似 # 局部配置 在视图类 views.py中配置: from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer class BookDetailView(APIView):     renderer_classes = [JSONRenderer, ]  # 全局设置 在配置文件中配置: REST_FRAMEWORK = {     'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类         'rest_framework.renderers.JSONRenderer',  # json渲染器         'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器     ) }

序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口

3、视图组件

# APIView   	from rest_framework.views import APIView      	类属性 renderer_classes,parser_classes... 	get方法,post方法,delete方法 写法跟之前的View一样,只不过request对象变成了新的request 	比之前的View多了三大认证和全局异常处理       # GenericAPIView  继承了APIView 但是多了属性和方法 	from rest_framework.generics import GenericAPIView      	属性(先记两个): 		queryset = None 		serializer_class = None          	方法: 		get_queryset 		get_object 		get_serializer                # 5个视图扩展类(不是视图类,没有集成APIView,需要配合GenericAPIView) 	from rest_framework.mixins import  		CreateModelMixin, 		ListModelMixin, 		DestroyModelMixin, 		RetrieveModelMixin, 		UpdateModelMixin          # 9个视图子类  	from rest_framework.generics import  		CreateAPIView, 		ListAPIView, 		DestroyAPIView, 		RetrieveAPIView, 		UpdateAPIView, 		ListCreateAPIView, 		RetrieveUpdateAPIView, 		RetrieveUpdateDestroyAPIView, 		RetrieveDestroyAPIView   # 视图集 	from rest_framework.viewsets import  		# 两个视图类 		ModelViewSet, ReadOnlyModelViewSet, 		# 视图类 		ViewSet, GenericViewSet, 		# 魔法类 		ViewSetMixin

继承GenericAPIView 重写视图类

# 添加路由:     path('publishs/<int:pk>', views.PublishDetailView.as_view()),           # 视图类复制过来并做修改: # 第一层:继承APIView写视图类  # 第二层:继承GenericAPIView写视图类 from rest_framework.generics import GenericAPIView  class PublishView(GenericAPIView):     queryset = Publish.objects.all()     serializer_class = PublishSerialzier      # 查询所有图书     def get(self, request):         # obj = self.queryset         obj = self.get_queryset()  # 等同于上面,obj = self.queryset 并且更好一些          # ser = self.serializers(instance=obj, many=True)         # ser=self.get_serializer_class()(instance=obj,many=True) # 等同于上面         ser = self.get_serializer(instance=obj, many=True)  # 等同于上面         return Response(ser.data)      # 新增图书数据     def post(self, request):         # ser = BookSerializer(data=request.data)         ser = self.get_serializer(data=request.data)  # 等同于上面         if ser.is_valid():             ser.save()             return Response({"code": 100, 'msg': '新增成功', 'data': ser.data})         return Response({"code": 101, 'msg': '新增失败', 'err': ser.errors})   class PublishDetailView(GenericAPIView):     queryset = Publish.objects.all()     serializer_class = PublishSerialzier      # 查询单条数据     def get(self, request, *args, **kwargs):         # book = Book.objects.all().filter(pk=pk).first()         obj = self.get_object()  # 等同于上面          # ser = BookSerializer(instance=book)         ser = self.get_serializer(instance=obj)  # 等同于上面         return Response(ser.data)      # 修改数据     def put(self, request, *args, **kwargs):         # book = Book.objects.all().filter(pk=pk).first()         obj = self.get_object()  # 等同于上面          # ser = BookSerializer(instance=book, data=request.data)         ser = self.get_serializer(instance=obj, data=request.data)  # 等同于上面         if ser.is_valid():             ser.save()             return Response({"code": 100, 'msg': '修改成功', 'data': ser.data})         return Response({"code": 101, 'msg': '修改出错', 'err': ser.errors})      # 删除数据     def delete(self, request, *args, **kwargs):         # Book.objects.filter(pk=pk).delete()         self.get_object().delete()         return Response({"code": 100, 'msg': '删除成功'})

序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口

4、通过GenericAPIView + 5个视图扩展类 重写视图类

# 第三层:GenericAPIView+5个视图扩展类 重写视图类 from rest_framework.generics import GenericAPIView from rest_framework.mixins import CreateModelMixin, ListModelMixin, DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin  class PublishView(GenericAPIView, CreateModelMixin, ListModelMixin):     queryset = Publish.objects.all()     serializer_class = PublishSerialzier      # 查询所有图书     def get(self, request):         return super().list(request)  # list(request)ListModelMixin的方法      # 新增图书数据     def post(self, request):         return super().list(request)  # create(request)ListModelMixin的方法   class PublishDetailView(GenericAPIView, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin):     queryset = Publish.objects.all()     serializer_class = PublishSerialzier      # 查询单条数据     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)

序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承GenericAPIView类重写接口