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

虚幻大学 xuhss 329℃ 0评论

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475

今日内容概要

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

内容详细

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()

"""
在每个表中写入数据一一对应
第五个自动创建的关联表 也写入数据
"""

b466c4d6b55fe51ba70fd8268f896074 - 序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承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/', views.BookView.as_view()),
]

b2950a4ac70a77822eace77f9d43dcb9 - 序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承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

# 总结:
    一般情况下,都使用默认即可,不用配置(三种格式数据都能解析)

4364424d8984acd28bbf342b48fe7813 - 序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承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渲染器
    )
}

8f65ef66a87eb36cc04f4bc9b1fc8ef8 - 序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承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/', 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': '删除成功'})

9e0eb6e29820f8459e3de94377b41eb7 - 序列化多表操作、请求与响应、视图组件(子类与拓展类)、继承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)

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

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

喜欢 (0)

您必须 登录 才能发表评论!