django_restful序列化和反序列化器验证和操作数据库

序列化器类

drf中都必须继承 Serializer
ModelSerializer 模型序列化器类 里面一定要包含 class Meta 声明调用的模型信息

反序列化器类

支持验证功能 age校验(max_value=100, min_value=0)
常用验证功能 max_length mim_length allow_black 是否允许为空 trim_whitespace 是否截断空白字符 max_value min_value
通用参数: read_only 仅用于序列化输出 默认False
write_only 仅用于反序列化输入 默认False
required 反序列化时必要输入字段 默认True
default 反序列化使用的默认值
allow_null 是否允许传入None 默认False
validators 字段使用验证器
error_messages 包含错误编码和错误信息的字典
label 用于html展示api页面时 显示字段名称
help_text 用于html展示api页面时,显示的字段帮助提示信息

数据验证

验证方法有三种

  1. 内部单个字段验证 validate_name
  2. 内部多个字段验证 validate
  3. 外部验证

serializers.py

from rest_framework import serializers
from snippets.models import Student
"""
序列化器类  drf中都必须继承 Serializer
ModelSerializer 模型序列化器类  里面一定要包含 class Meta 声明调用的模型信息
"""


class Student1Serializer(serializers.Serializer):
    """学生信息序列化器类"""
    # 转换的字段声明
    id = serializers.IntegerField()
    name = serializers.CharField()
    sex = serializers.IntegerField()
    # sex = serializers.BooleanField()
    age = serializers.IntegerField()
    code = serializers.CharField()
    classmate = serializers.CharField()
    desc = serializers.CharField()

    # class Meta:
    #     model = Snippet
    #     fields = ('id', 'title', 'code', 'linenos', 'language', 'style',)

    # 验证代码的对象方法
    def validate(self, attrs):  # validate是固定的
        pass
        return attrs

    # def validate_<字段名>(self, data):  # 方法名的格式必须以validate_<字段名> 为名称 否则序列化器不识别
    #     pass
    #     return data

    # 模型操作的方法
    def create(self, validated_data):  # 添加数据就实现了从字典到模型对象的过程
        pass

    def update(self, instance, validated_data):  # 添加数据后就实现了从字典到模型对象的过程
        pass


"""
反序列化器类  支持验证功能  age校验(max_value=100, min_value=0)
常用验证功能  max_length mim_length  allow_black 是否允许为空 trim_whitespace 是否截断空白字符 max_value min_value
通用参数: read_only 仅用于序列化输出 默认False
write_only  仅用于反序列化输入 默认False
required 反序列化时必要输入字段 默认True
default 反序列化使用的默认值
allow_null 是否允许传入None 默认False
validators 字段使用验证器
error_messages 包含错误编码和错误信息的字典
label 用于html展示api页面时 显示字段名称
help_text 用于html展示api页面时,显示的字段帮助提示信息
"""

"""
验证方法有三种
1. 内部单个字段验证  validate_name
2. 内部多个字段验证  validate
3. 外部验证
"""


# 外部验证   为了方便多个模块使用同一个验证, 可以导包重复使用
def check_classmate(data):
    """
    data
    """
    if len(data) != 3:
        raise serializers.ValidationError(detail="班级号必须为3位", code="check_classmate")
    # 验证成功必须返回 否则验证结果没有该数据
    return data


class Student2Serializer(serializers.Serializer):
    """学生信息序列化器类
    error_messages 是自定义错误
    """
    # 转换的字段声明
    id = serializers.IntegerField(read_only=True)  # 在反序列化的时候不要求id字段
    # name = serializers.CharField(required=True, error_messages={"required": "name为必传字段"})  # 返序列化必填
    name = serializers.CharField(required=True)  # 返序列化必填
    sex = serializers.IntegerField(default=1)  # 默认值为1
    # sex = serializers.BooleanField()
    age = serializers.IntegerField(max_value=100, min_value=0,
                                   error_messages={"max_value": "年龄范围0-100", "min_value": "年龄范围0-100"})  # 100>age>0
    code = serializers.CharField()
    # 外部验证函数选项 参数是函数名
    classmate = serializers.CharField(validators=[check_classmate])
    desc = serializers.CharField(allow_null=True, allow_blank=True)  # 允许不传 或者传空白过来

    # 验证复杂逻辑 验证name
    def validate_name(self, data):
        """验证name字段
        方法名的格式必须以validate_<字段名> 为名称 否则序列化器不识别
        view里面使用的is_valid调用validate_
        data 是name字段值
        """
        if data in ["python", "james"]:
            # 在序列化器中抛出异常来告知is_valid
            raise serializers.ValidationError(detail="姓名不能是python或james", code="validate_name")
        # 验证成功之后一定要返回数据
        return data

    # 验证所有的参数
    def validate(self, attrs):  # validate是固定的
        """
        验证来自客户端的所有数据
        参数attrs/data  就是views里面调用serializer类时传过来的data
        """
        # 女生的名字不能叫小明
        if attrs['name'] == "xiaoming" and attrs["sex"] == 0:
            raise serializers.ValidationError(detail="女生的名字不能叫小明", code="validate")
        return attrs

    """
    操作数据库
    """
    def create(self, validated_data):
        """数据库添加数据"""
        student = Student.objects.create(**validated_data)
        return student

    def update(self, instance, validated_data):
        """数据库更新数据"""
        instance.name = validated_data["name"]
        instance.age = validated_data["age"]
        instance.sex = validated_data["sex"]
        pass
        instance.save()  # 调用模型对象的save
        return instance

views.py

import json

from django.shortcuts import render
from django.views import View

from .serializers import Student1Serializer, Student2Serializer
from django.http.response import JsonResponse
from snippets.models import Student


class StudentView(View):
    def get1(self, request):
        """序列化器类"""
        # students_list = Student.objects.all()
        students_list = [
            {"id": 1, "name": "age", "sex": 1, "age": 12, "code": "ad", "classmate": "12", "desc": "122"},
            {"id": 2, "name": "xiaoming", "sex": 1, "age": 34, "code": "2323", "classmate": "6", "desc": "dsf3r4"},
            {"id": 3, "name": "周", "sex": 1, "age": 14, "code": "123", "classmate": "12", "desc": "123"}
        ]  # many=True
        student = {"id": 1, "name": "age", "sex": 1, "age": 12, "code": "ad", "classmate": "12",
                   "desc": "122"}  # many=False
        # student = [{"id": 1, "name": "age", "sex": 1, "age": 12, "code": "ad", "classmate": "12", "desc": "122"}]  # many=True

        # 实例化序列化器 得到序列化对象  序列化多个要加many=True
        serializer = Student1Serializer(instance=students_list, many=True)
        # serializer = Student1Serializer(instance=student, many=True)

        # 调用序列化对象的data属性方法获取转换后的数据
        data = serializer.data

        # 响应数据
        return JsonResponse(data=data, status=200, safe=False, json_dumps_params={'ensure_ascii': False})

    def get(self, request):
        """反序列化 采用字段选项来验证"""
        # data = json.dumps(request.body)
        data = {
            # "name": "james",
            # "name": None,
            "name": "xiaoming",
            "age": 42,
            "sex": 0,
            "code": 125,
            "classmate": "1355",
            "desc": None
        }

        # 调用序列化器验证
        serializer = Student2Serializer(data=data)
        res = serializer.is_valid()  # 不抛出异常
        # res = serializer.is_valid(raise_exception=True)  # 抛出异常  由try except 统一处理错误结果
        print(res)

        # # 操作数据
        # if res:
        #     print(serializer.validated_data)
        #     info = {"status": 200, "data": "ok"}
        #     return JsonResponse(data=info, status=200, safe=False, json_dumps_params={'ensure_ascii': False})
        # else:
        #     print(serializer.error_messages)
        #     print(serializer.errors)
        #     info = {"status": 400, "data": None, "error": serializer.errors}
        #     print("data is None")
        #
        #     return JsonResponse(data=info, status=400, safe=False, json_dumps_params={'ensure_ascii': False})

        # 操作验证之后的数据到数据库
        serializer.save()  # save通过是否传入instance判断调用create或update 传入instance自动调用update  不传调用create
        # serializer.create()  # 如果是create的话 要传参数
        # serializer.update(instance=)  # 如果是create的话 要传参数
        print(serializer.data)
        return JsonResponse(serializer.data, status=201, safe=False, json_dumps_params={'ensure_ascii': False})

    def post(self, request):
        """
        更新数据库
        反序列化 采用字段选项来验证"""
        # data = json.dumps(request.body)
        data = {
            # "name": "james",
            # "name": None,
            "name": "xiaoming",
            "age": 42,
            "sex": 0,
            "code": 125,
            "classmate": "1355",
            "desc": None
        }

        # 调用序列化器验证  update 要传 instance
        serializer = Student2Serializer(instance=Student, data=data)
        res = serializer.is_valid()  # 不抛出异常
        # res = serializer.is_valid(raise_exception=True)  # 抛出异常  由try except 统一处理错误结果
        print(res)

        # # 操作数据

        # 操作验证之后的数据到数据库
        serializer.save()  # save通过是否传入instance判断调用create或update 传入instance自动调用update  不传调用create
        # serializer.create()  # 如果是create的话 要传参数
        # serializer.update(instance=)  # 如果是create的话 要传参数
        print(serializer.data)
        return JsonResponse(serializer.data, status=201, safe=False, json_dumps_params={'ensure_ascii': False})


model.py

class Student(models.Model):
    name = models.CharField(max_length=100, blank=True, default='', verbose_name="姓名")
    sex = models.BooleanField(default=1)
    age = models.IntegerField(verbose_name="年龄", help_text="年龄不能小于0")
    code = models.TextField()
    classmate = models.CharField(max_length=5, verbose_name="班级编号")
    desc = models.TextField(verbose_name="个性签名")

    class Meta:
        db_table = 'tb_student'
        verbose_name = "学生"
        verbose_name_plural = verbose_name
        # ordering = ['created']
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BRYTLEVSON

打赏的都是天使,创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值