django rest_framework序列化器的使用(八)

一.rest_framework介绍

官网网站: https://www.django-rest-framework.org/api-guide/requests/

1.简介

a. 是在django的基础上进行的二次开发
b. 用于构建restful api
c. 简称为DRF框架

2. 特性

a. 提供了强大的Serializer序列化器类,可以高效的进行序列化和反序列化操作
b. 提供了极为丰富的类视图、Mixin扩展类、ViewSet视图集;
c. 提供了直观的Web API界面
d. 多种身份认证和权限认证
e. 强大的排序、过滤、分页、搜索、限流等功能
f. 可扩展性、插件丰富

3.安装

a. pip install djangorestframework
可选 #pip install markdown
可选 #pip install django-filter
b.
INSTALLED_APPS = [

‘rest_framework’, ]

二. 实战使用

1.示例一:Serializer类

a. models.py文件

# models.py文件
from django.db import models
class Projects(models.Model):
	
	    id = models.AutoField(primary_key=True)
	    name = models.CharField(max_length=200, verbose_name='项目名称', help_text='项目名称', unique=True)
	    leader = models.CharField(max_length=50, verbose_name='项目负责人', help_text='项目负责人')
	    tester = models.CharField(max_length=50, verbose_name='测试人员', help_text='测试人员')
	    programmer = models.CharField(max_length=50, verbose_name='开发人员', help_text='开发人员')
	    desc = models.TextField(verbose_name='项目简介', help_text='项目简介', blank=True, default='xxx简介', null=True)
	    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
	    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
	
	    # 执行迁移脚本之后,生成的数据表名默认为 子应用名_模型类名小写
	    class Meta:
	        db_table = 'tb_projects'
	        verbose_name = '项目表'
	
	    def __str__(self):
	        return f"<{self.name}>"

b. serializers.py文件

ProjectSerializses类必须继承serializers.Serializer类
ProjectSerializses类中的字段属性必须与models.py中的对应

# serializers.py文件
from rest_framework import serializers


class ProjectSerializses(serializers.Serializer):
	
	# label对应models模型类中的verbose_name
    name = serializers.CharField(max_length=30, label="项目名称", help_text="项目名称")
    leader = serializers.CharField(max_length=20, label="项目负责人", help_text="项目负责人",write_only=True,required=False)
    tester = serializers.CharField(max_length=20,label="测试人员", help_text="测试人员",error_messages={
    
    "required":"这是必传参数22"})

c. views.py文件

class LoginPage(View):

    def get(self,request):
        """
        输出所有的项目信息
        :param request:
        :return:
        """
        # 获取查询集—》传给序列化器,对于查询集对象,需要传many=True(对于单个模型类对象则不需要)
        qs = Projects.objects.all()
        ser = ProjectSerializses(instance=qs,many=True)
        result = {
    
    "code": "0", "message": "success", "data": ser.data}
        return JsonResponse(result, safe=False)

    def post(self, request):
    	"""
    	创建项目
    	:param request:
        :return:
    	"""
        # 1.获取请求参数
        resquest_data = request.body
        try:
            # 2. 反序列化输入(将json字符串转化为python字典)
            resquest_data = json.loads(resquest_data)
        except:
            result_data = {
    
    "code": "1", "message": "请求参数有误"}
            return JsonResponse(result_data, safe=False, status=200)

        ser = ProjectSerializses(data=resquest_data)
        try:
        	# 会将前端传入的参数使用序列化器进行校验
            ser.is_valid(raise_exception=True)
        except:
        	# 校验失败可以使用ser.errors进行输出
            result_data = {
    
    "code": "2", "message": "请求参数有误","data":ser.errors}
            return JsonResponse(result_data, safe=False, status=200)

        # 3. 进行数据库操作
        Projects.objects.create(**resquest_data)
        
        # 4.序列化输出(将模型类对象转换为json字符串)
        # result = {"code": "0", "message": "success", "data": model_to_dict(obj)}
		# ser.validated_data是校验前端结束后的数据
		# ser.data是从查询集中拿到数据后去除掉,序列化器中没有的以及write_only=True的
        result = {
    
    "code": "0", "message": "success", "data": ser.data}
        return JsonResponse(result, safe=False)

d. 测试结果
在这里插入图片描述
在这里插入图片描述

2.示例二:ModelSerializer类及其校验

a.serializers.py文件

def is_start_xx(value):
    if str(value).startswith("xx"):
        raise serializers.ValidationError("不能以xx开头")

class ProjectSerializses(serializers.ModelSerializer):
    name = serializers.CharField(max_length=30, label="项目名称", help_text="项目名称",
                                 validators=[validators.UniqueValidator(queryset=Projects.objects.all(),
                                                                        message="name字段只能是唯一的"),is_start_xx],
                                 error_messages={
    
    "required":"name字段必传"})

    class Meta:
        # 必须指定model,指定要映射的模型类
        model = Projects
        # 1.fields和exclude不能同时存在
        # 2.fields=("name","leader"),可以指定某一个或几个字段
        fields = "__all__"  # 指定所有

        # exclude中的字段是既不输入也可以不输出
        # exclude = ("create_time","update_time")

        # extra_kwargs说明:
        # 1.若是在序列化器类中定义了同名类属性则在extra_kwargs写的则无效,
        # 2.若是没定义类属性,则满足覆盖添加原则
        extra_kwargs = {
    
    
            "leader": {
    
    
                "max_length": 5,

            }
        }

    # 单字段校验:校验方式是以validate_字段名称
    def validate_name(self, name):
        if str(name).endswith("xx"):
            raise serializers.ValidationError("不能以xx结尾")
        return name

    # 多字段校验:直接使用validate,但是必须返回attrs
    def validate(self, attrs):
        name = attrs["name"]
        leader = attrs["leader"]
        if re.search(r"##",name) and  re.search(r"##",leader):
            raise serializers.ValidationError("name和leader中不能同时包含#")
        return attrs

b. views.py文件

class ProjectsView(View):

    def get(self,request):
        """
        输出所有的项目信息
        :param request:
        :return:
        """
        # 获取查询集—》传给序列化器,对于查询集对象,需要传many=True(对于单个模型类对象则不需要)
        qs = Projects.objects.all()
        ser = ProjectSerializses(instance=qs,many=True)
        result = {
    
    "code": "0", "message": "success", "data": ser.data}
        return JsonResponse(result, safe=False)

    def post(self, request):
        # 1.获取请求参数
        resquest_data = request.body
        try:
            # 2. 反序列化输入(将json字符串转化为python字典)
            resquest_data = json.loads(resquest_data)
        except:
            result_data = {
    
    "code": "1", "message": "请求参数有误"}
            return JsonResponse(result_data, safe=False, status=200)

        ser = ProjectSerializses(data=resquest_data)
        try:
            ser.is_valid(raise_exception=True)
        except:
            result_data = {
    
    "code": "2", "message": "请求参数有误","data":ser.errors}
            return JsonResponse(result_data, safe=False, status=200)

        # 3. 进行数据库操作
        # obj = Projects.objects.create(**resquest_data)
        ser.save()

        # 4.序列化输出(将模型类对象转换为json字符串)
        # result = {"code": "0", "message": "success", "data": model_to_dict(obj)}
        result = {
    
    "code": "0", "message": "success", "data": ser.data}

        return JsonResponse(result, safe=False)


class ProjectDetailView(View):

    def get(self,request,pk):
        ser = ProjectSerializses(instance=Projects.objects.get(id=pk))
        result = {
    
    "code": "0", "message": "success", "data": ser.data}
        return JsonResponse(result, safe=False)

3.总结

1.序列化器可以用来进行参数校验
2.创建数据时:可以重写或者继承ModelSerializer中的create()方法(可选的)—>在view中使用序列化器中只传入data参数时,然后使用对象.save()方法可以进行数据的创建(用户post方法)
3.更新数据时:可以重写或者继承ModelSerializer中的update()方法(可选的)—>序列化器中传入instance和data参数时,然后使用对象.save()方法可以进行数据的更新(用于put和patch方法)
4.查询所有数据时:序列化器类中只需要传入查询集和many=True即可
在这里插入图片描述

5.查询单个数据时:序列化器类中只需要传入instance即可
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43534980/article/details/111409509
今日推荐