Django-rest-framework 接口实现 Serializer 使用

Django接口实现 DRF

使用 以下模块 实现 json数据 序列化

博客: https://www.cnblogs.com/liwenzhou/p/9959979.html

Django REST Framework

​ 查看全局的 DRF 配置: rest_framework.settings

  • 基于Django开发RESTful API的一个框架
  • django 中使用
  1. 安装模块

    pip install djangorestframework

  2. 使用的时候

    使用 rest_framework 这个名字

Serializer 使用

  • 以图书管理为基础 操作
    • Books 图书
    • Author 作者
    • Publisher 出版社
  1. 注册APP 'rest_framework', 不是必须的 需要好看的界面 就注册

  2. 在views 视图中 使用

    CBV写法:

    1. 导入APIView from rest_framewor.views import APIView, CBV继承它

    2. 响应对象 使用 rest_framework 中的 响应 Response

      from rest_framework.response import Response

    3. 在app中 创建一个 serializers 的 py文件 创建 序列化工具类 并将其导入 用法 跟Form 基本类似

      from interface.serializers import BooksSerializer

    CBV视图中注意事项:

    • 写上类注释 会在 chream 浏览器中 提示 相当于 文档提示

    • 实例化的 serializer 对象 接收 参数

      BooksModelSerializer(query_set_list, many=True)

      BooksSerializer(instance=book_obj)

      BooksSerializer(instance=book_obj, data=request.data, partial=False)

      queryset对象直接放在第一个位置 交给 工具序列化 many=True 需要有多个会循环读取

      instance 需要单个的书籍对象 data=需要校验的数据 partial=False 可以对单个值进行修改

    • 返回的 数据 ser_obj.data 就是序列化的 json 数据 APIView 包装的 数据 直接用 Reaponse 返回

    • 提交修改的数据put数据 request.data

    • 路由上携带的 参数 request.query_params

    • request 不是之前的 request 对象 self._requrst 才是之前的 request

    • 使用 res_obj.save() 需要在 serializer 中 重写 create() 方法

    • 修改数据时 错误信息 是 ser_obj.errors 直接返回

    class BooksList(APIView):
        ''' books书籍 接口 :支持查询所有书籍 GET请求 添加书籍 POST请求 '''
        def get(self, request):
            '''获取所有的书籍'''
            query_set_list = models.Books.objects.all()
            ser_obj = BooksModelSerializer(query_set_list, many=True)
            return Response(ser_obj.data)
    
        def post(self, request):
            # 将  数据交给 serializer  books序列化的  工具进行效验
            ser_obj = BooksSerializer(data=request.data)
            print(request.data)
            if ser_obj.is_valid():
                # serializer 中 调用 save()  方法  需要 重写 create()  方法
                ser_obj.save()
                return Response('ok')
            else:
                return Response(ser_obj.errors)
            
    class BookDetails(APIView):
        ''' 单本书籍的操作  支持 GET/PUT/DELETE '''
        def get(self, request, pk):
            '''单本书籍的查询'''
            book_obj = models.Books.objects.filter(pk=pk).first()
            if book_obj:
                ser_obj = BooksSerializer(instance=book_obj)
                return Response(ser_obj.data)
            
        def put(self, request, pk):
            '''单本书籍的修改'''
            book_obj = models.Books.objects.filter(pk=pk).first()
            if book_obj:
                #  partial=True 可以局部更新
                ser_obj = BooksSerializer(instance=book_obj, data=request.data, partial=False)
                if ser_obj.is_valid():
                    ser_obj.save()   # 调用 类中的update() 方法
                    return Response(ser_obj.data)
                else:
                    return Response(ser_obj.errors)
                
        def delete(self, request, pk):
            '''删除某一本书籍'''
            book_queryset = models.Books.objects.filter(pk=pk)
            if book_queryset:
                book_queryset.delete()
                return Response('删除成功!!')
    
    
  3. 自己写一个序列化的工具类 BookSerializer

    工具类写法:

    • 导入 serializers

      from rest_framework import serializers

    • 创建类 继承 serializers.Serializer

    • 填写 需要序列化的 字段

    • 重写 create(self,validated_data) 方法 以及 update(self, instance, validated_data):方法

      validates_date 就是通过校验的数据 instance 是 单个的 数据对象

    • 局部钩子 def validate_字段名(self, attrs): 全局钩子 :def validate(self, attrs):

    注意事项:

    • id字段 需要填写 参数required=False 修改此字段在新建数据时不是必须的 可以不写
    • 字段名要跟models 中的字段名对应
    • 字段参数使用 serializers.字段类型 进行设置 参数填写 max_length=32...等参数进行效验

特殊字段的 显示

  • 写两个字段 一个用来读取 一个用来添加 使用 read_only=Truewrite_only=True区分
  1. choices 显示

    参数cource='get_字段名_display'来显示具体对应的 内容

  2. ForeignKey 显示

    自定义一个对应的 外键 序列化类 进行显示

  3. ManTOMan 字段显示

    多个内容 使用 many=true 的参数 来取多个值 同样创建一个字段对应的序列化类

写入效验的 字段 变量面前需要加 post_字段名来区分 写入时字段名要对应

  • create() 中就是 orm 操作 validated_data 就是通过效验的数据

    注意字段中存的 具体数据类型

    需要返回 创建好的 obj 的对象

  • update() 中也是 orm 操作 instance 就是要修改的 单本书的数据 validated_data通过校验的数据

    需要返回 instence

  • 钩子中 不通过效验 需要抛出 serializers 中的 ValidationError

    raise serializers.ValidationError('不通过效验 就抛出异常')

'''
这是一个 Django rest framework 的  json 序列化的 工具
'''
from rest_framework import serializers
from interface import models

class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    name = serializers.CharField(max_length=32)

class PublisherSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    name = serializers.CharField(max_length=32)

class BooksSerializer(serializers.Serializer):
    # 普通字段的 显示
    id = serializers.IntegerField(required=False)
    # validators 自定义效验规则
    title = serializers.CharField(max_length=32,validators=[func])
    pub_date = serializers.DateField(required=False)

    # choices 字段 特殊显示
    booksType = serializers.CharField(source='get_booksType_display', read_only=True)
    post_booksType = serializers.IntegerField(write_only=True)

    # ForeignKey  字段特殊显示
    publisher = PublisherSerializer(read_only=True)
    post_publisher = serializers.IntegerField(write_only=True)

    # ManyToManyField 字段特殊显示
    authors = AuthorSerializer(many=True, read_only=True)
    post_authors = serializers.ListField(write_only=True)

    def validate(self, attrs):
        '''全局 校验 '''
        return attrs

    def validate_title(self, attrs):
        ''' 单一字段的校验 '''
        if "av" in attrs:
            raise serializers.ValidationError('不通过效验 就抛出异常')
        return attrs
	
    # 行内校验:
    	# 自定义函数  给出字段参数 validators=[func]
    
    def create(self, validated_data):
        '''重写 create() 方法 使用 save() 方法 写入数据库'''
        # validated_data  就是通过效验的数据
        print(validated_data)
        # 正常字段 以及外键的创建
        book_obj = models.Books.objects.create(
            title=validated_data['title'],
            booksType=validated_data['post_booksType'],
            publisher_id=validated_data['post_publisher'],
        )
        # 多对多的创建
        book_obj.authors.set(validated_data['post_authors'])
        return book_obj

    def update(self, instance, validated_data):
        # print(instance)  # 要更新的 book  对象
        # print(validated_data)   #  通过校验的数据
        instance.title = validated_data.get('title', instance.title)
        instance.booksType = validated_data.get('post_booksType', instance.booksType)
        instance.publisher_id = validated_data.get('post_publisher', instance.publisher_id)
        # 将表内的数据存入数据库中
        instance.save()
        # 修改 多对多字段
        instance.authors.set(validated_data.get('post_authors', [i['id'] for i in instance.authors.all().values('id')]))

        return instance

  1. 在视图中 使用queryset数据实例化得到一个 序列化对象 --》 ser_obj 并返回数据

    ser_obj = BooksSerializer(instance=book_obj)
                return Response(ser_obj.data)
    
posted @ 2019-02-27 21:58  拐弯  阅读(789)  评论(0编辑  收藏  举报