• DRF的序列化组件


    rest

    rest下的url

    url唯一代表资源,http请求方式来区分用户行为

    url的设计规范

    GET: 127.0.0.1:9001/books/        # 获取所有数据

    GET: 127.0.0.1:9001/books/{id}      # 获取单条数据

    POST: 127.0.0.1:9001/books/      # 增加数据

    DELETE: 127.0.0.1:9001/books/{id}    # 删除数据

    PUT: 127.0.0.1:9001/books/{id}      # 修改数据

    数据响应规范

    GET: 127.0.0.1:9001/books/        # 返回[{}, {}, {}]

    GET: 127.0.0.1:9001/books/{id}      # {} 单条数据

    POST: 127.0.0.1:9001/books/        # {} 添加成功的数据

    DELETE: 127.0.0.1:9001/books/{id}    # "" 返回空

    PUT: 127.0.0.1:9001/books/{id}      # {} 更新后完整的数据

    错误处理

    { "error": "message" }

    解析器组件

    • 解析器组件是用来解析用户请求的数据的(application/json), content-type

    • 必须继承APIView

    • request.data触发解析

    APIView的使用

    rest_framework是一个app需要在settings里设置

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',  
    ]

    pip install djangorestframework

    from rest_framework.views import APIView

    class LoginView(APIView):
    def get(self, request):
    pass

    序列化组件

    Django自带的serializer

    from django.serializers import serialize  # 引入
    ​
    origin_data = Book.objects.all()
    serialized_data = serialize("json", origin_data)

    DRF的序列化组件

    接口设计

    from rest_framework import serializers  #引入

    创建一个序列化类

    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = Book
            # model字段
            fields = ('title',
                      'price',
                      'publish',
                      'authors',
                      'author_list',
                      'publish_name',
                      'publish_city'
                      )
            # 只需写入不需要展示的字段
            extra_kwargs = {
                'publish': {'write_only': True},
                'authors': {'write_only': True}
            }
        # source为自定义需要展示的信息
        publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name')
        publish_city = serializers.CharField(max_length=32, read_only=True, source='publish.city')
        # 多对多字段需要自己手动获取数据,SerializerMethodField()
        author_list = serializers.SerializerMethodField()
    ​
        def get_author_list(self, book_obj):
            # 拿到queryset开始循环 [{}, {}, {}, {}]
            authors = list()
    ​
            for author in book_obj.authors.all():
                authors.append(author.name)
    ​
            return authors
    创建序列化类

    开始序列化

    get接口(查询多条数据) & post接口

    class BookView(APIView):
        def get(self, request):
            # 获取queryset
            origin_data = Book.objects.all()
            # 开始序列化
            serialized_data = BookSerializer(origin_data, many=True)
            return Response(serialized_data.data)
        def post(self, request):
            verified_data = BookSerializer(data=request.data)
            if verified_data.is_valid():
                book = verified_data.save()
                authors = Author.objects.filter(nid__in=request.data['authors'])
                book.authors.add(*authors)
                return Response(verified_data.data)
            else:
                return Response(verified_data.errors)

    get(查询单条数据) & put接口 & delete接口

    class BookFilterView(APIView):
        def get(self, request, nid):
            book_obj = Book.objects.get(pk=nid)
            serialized_data = BookSerializer(book_obj, many=False)
            return Response(serialized_data.data)
    ​
        def put(self, request, nid):
            book_obj = Book.objects.get(pk=nid)
            verified_data = BookSerializer(data=request.data, instance=book_obj)
            if verified_data.is_valid():
                verified_data.save()
                return Response(verified_data.data)
            else:
                return Response(verified_data.errors)
    ​
        def delete(self, request, nid):
            book_obj = Book.objects.get(pk=nid).delete()
            return Response()

    缺点:

    serializers.Serializer无法插入数据,只能自己实现create字段太多,不能自动序列化

    接口设计优化

    使用视图组件的mixin进行接口逻辑优化

    导入mixin

    from rest_framework.mixinx import (
                        ListModelMix,
                        CreateModelMixin,
                        DestroyModelMixin,
                        UpdateModelMixin,
                        RetrieveModelMixin
                    )
    from rest_framework.generics import GenericAPIView
    ​

    定义序列化类

    Class BookSerializer(serializers.ModelSerializer):
                      class Meta:
                          Book
                          fields = ()
                          ...如上

    因为使用模块化编程,建议将定义的序列化类放在单独的模块中,再在view.py中导入

    from .app_serializers import BookSerializer

    定义视图类​

    class BookView(ListModelMix, CreateModelMixin, GenericAPIView):
        # queryset和serializer_class是固定的写法
        queryset = Book.objects.all()
        serializer_class = BookSerializer      
        def get():
            return self.list() # 查询多条
                
        def post():
            return self.create()
                    
    class BookFilterView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
    ​
        def get():
            return self.retrieve()  # 查询单条
    def delete():
            return self.destroy()
    ​
        def put():
            return self.update()

    注意:

    查询单挑数据的url需要给查询的id进行正则分组

    re_path(r'books/(?P<pk>d+)/$, views.BookFilterView.as_view())

    使用视图组件的view进行接口逻辑优化

    导入模块

    from rest_framework import generics

    视图类​

    class BookView(generics.ListCreateAPIView)
        queryset = Book.objects.all()
        serializer_class = BookSerializer   
    class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer

    使用视图组件的viewset进行接口逻辑优化

    导入模块

    from rest_framework.viewsets import ModelViewSet

    设计url

    re_path(r'books/$, views.BookView.as_view({
        'get': 'list',
        'post': 'create'
        })),
    re_path(r'books/(?P<pk>d+)/$', views.BookView.as_view({
        'get': 'retrieve',
        'delete': 'destroy',
        'put': 'update'
        }))

    设计视图类

    class BookView(ModelViewSet):
        queryset = Book.objects.all()
        serializer_class = BookSerializer

     

     

  • 相关阅读:
    springboot @value 注解的使用
    Django时间时区问题(received a naive datetime while time zone support is active
    乐观锁与悲观锁
    Django 从入门到放弃
    根据数据库表生成 model 类
    Django CSRF攻击
    Django的orm的 数据库查询语法大全
    js常用函数、书写可读性的js、js变量声明...
    Web Worker
    css编写规范
  • 原文地址:https://www.cnblogs.com/jiaqi-666/p/9416528.html
Copyright © 2020-2023  润新知