11 DRF-数据校验

序列化:
    - 路由 -> 视图 -> 去db获取数据 -> 转换成Json对象{}&[] -> JSON处理
数据校验:
    - 路由 -> 视图 -> request.data -> 校验(序列化器的类) -> 操作(db,序列化器的类)
结合:
    创建用户请求:{"user":"","password":""}
        - 校验(序列化器的类)
        - 数据库新增的对象 = 链接数据库(保存)
        - 在将新增的数据返回
            在此调用(序列化器的类),让它新增的数据 序列化返回

潜规则-请求方式详解:

	api/v1/user/	->GET请求	->获取数据列表	models.UserInfo.objects.all()
	api/v1/user/2/	->GET请求	->获取单个数据	models.UserInfo.objects.filter(id=2).first()

	api/v1/user/	->POST请求	->新增数据
	api/v1/user/3/	->PUT请求	->更新数据


序列化 read_only:
	ser = DepartSerializer(instance=对象, many=True)
	ser = DepartSerializer(instance=对象, many=False)

数据校验 write_only:
	ser = DepartSerializer(data=request.data)
	if ser.is_valid():
		print(ser.validated_data)
		more = ser.validated_data.pop("more")
		ser.save(count=100)  # 自定义添加字段参数
	else:
		print(ser.error)

1 内置校验

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers


class InfoSerializer(serializers.Serializer):
    title = serializers.CharField(required=True, max_length=20, min_length=6)
    order = serializers.IntegerField(required=False, max_value=100, min_value=10)
    level = serializers.ChoiceField(choices=[("1", "高级"), (2, "中级")])


class InfoView(APIView):
    def post(self, request):
        ser = InfoSerializer(data=request.data)
		# 方式1:
        if ser.is_valid():
            return Response(ser.validated_data)
        else:
            return Response(ser.errors)
		
		# 方式2:
		# ser.is_valid(raise_exception=True)  # 校验成功继续往下走,失败抛出异常返回前端数据
        # print(ser.validated_data)
        # return Response('成功')

2 正则校验

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from django.core.validators import RegexValidator, EmailValidator


class InfoSerializer(serializers.Serializer):
    title = serializers.CharField(required=True, max_length=20, min_length=6)
    order = serializers.IntegerField(required=False, max_value=100, min_value=10)
    level = serializers.ChoiceField(choices=[("1", "高级"), (2, "中级")])

    # email = serializers.EmailField()
    email = serializers.CharField(validators=[EmailValidator(message="邮箱格式错误")])

    more = serializers.CharField(validators=[RegexValidator(r"\d+", message="格式错误")])

    code = serializers.CharField()


class InfoView(APIView):
    def post(self, request):
        ser = InfoSerializer(data=request.data)
        if ser.is_valid():
            return Response(ser.validated_data)
        else:
            return Response(ser.errors)

3 钩子校验

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import exceptions


class InfoSerializer(serializers.Serializer):
    title = serializers.CharField(required=True, max_length=20, min_length=6)
    order = serializers.IntegerField(required=False, max_value=100, min_value=10)
    code = serializers.CharField()

    def validate_code(self, value):
        print(value)
        if len(value) > 6:
            raise exceptions.ValidationError("字段钩子校验失败")
        return value

    def validate(self, attrs):
        print("validate=", attrs)
        # api_settings.NON_FIELD_ERRORS_KEY  # 全局配置,修改抛出错误的key
        # raise exceptions.ValidationError("全局钩子校验失败")
        return attrs


class InfoView(APIView):
    def post(self, request):
        ser = InfoSerializer(data=request.data)
        if ser.is_valid():
            return Response(ser.validated_data)
        else:
            return Response(ser.errors)

4 Model校验

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import exceptions
from api import models
from django.core.validators import RegexValidator


class RoleSerializer(serializers.ModelSerializer):
    more = serializers.CharField(required=True)

    class Meta:
        model = models.Role
        fields = ["title", "order", "more"]
        extra_kwargs = {
            "title": {"validators": [RegexValidator(r"\d+", message="格式错误")]},
            "order": {"min_value": 5},
        }

    def validate_more(self, value):
        return value

    def validate(self, attrs):
        return attrs


class InfoView(APIView):
    def post(self, request):
        ser = RoleSerializer(data=request.data)
        if ser.is_valid():
            return Response(ser.validated_data)
        else:
            return Response(ser.errors)

5 校验+保存

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import exceptions
from api import models
from django.core.validators import RegexValidator


class RoleSerializer(serializers.ModelSerializer):
    more = serializers.CharField(required=True)

    class Meta:
        model = models.Role
        fields = ["title", "order", "more"]
        extra_kwargs = {
            "title": {"validators": [RegexValidator(r"\d+", message="格式错误")]},
            "order": {"min_value": 5},
        }

    def validate_more(self, value):
        return value

    def validate(self, attrs):
        return attrs


class InfoView(APIView):
    def post(self, request):
        ser = RoleSerializer(data=request.data)
        if ser.is_valid():
            # 情况1:
            ser.validated_data.pop("more")
            instance = ser.save()  # ser.save(v1=123,v2=234)
            # 情况2:
            # ser.save(more='大烧饼')
            print(instance)
            return Response(ser.validated_data)
        else:
            return Response(ser.errors)

6 校验+保存+FK+M2M

from django.db import models


class Role(models.Model):
    title = models.CharField(verbose_name="标题", max_length=32)
    order = models.IntegerField(verbose_name="顺序")


class Tag(models.Model):
    caption = models.CharField(verbose_name="名称", max_length=32)


class UserInfo(models.Model):
    name = models.CharField(verbose_name="姓名", max_length=32)
    gender = models.SmallIntegerField(verbose_name="性别", choices=((1, "男"), (2, "女")))
    role = models.ForeignKey(verbose_name="角色", to="Role", on_delete=models.CASCADE)
    ctime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)

    tags = models.ManyToManyField(verbose_name="标签", to="Tag")
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import exceptions
from api import models
from django.core.validators import RegexValidator
import datetime


class UserInfoSerializer(serializers.ModelSerializer):
    more = serializers.CharField(required=True)

    class Meta:
        model = models.UserInfo
        fields = ["name", "gender", "role", "tags", "more"]
        extra_kwargs = {
            "name": {"validators": [RegexValidator(r"n-\d+", message="格式错误")]},
        }
        
    def validate_role(self, value):
        # value是一个对象
        if value.id > 1:  # 多对多表中的id大于1返回该值(排除某个数据)
        	return value
		raise exceptions.ValidationError("角色错误")

    def validate_tags(self, value):
        # value是一个 [obj1, obj2]
        return value

    def validate(self, attrs):
        return attrs


class InfoView(APIView):
    def post(self, request):
        ser = UserInfoSerializer(data=request.data)
        if ser.is_valid():
            ser.validated_data.pop("more")
            instance = ser.save(ctime=datetime.datetime.now())
            print(instance)
            # return Response(ser.validated_data)
            return Response("成功")
        else:
            return Response(ser.errors)

image


7 关于FK的ID问题

image

image


8 关于M2M自定义问题

image

image


posted @ 2022-10-21 09:41  角角边  Views(93)  Comments(0)    收藏  举报