Django Rest_Framework初始之序列化器和反序列化

一.RESTful API规范

REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。 它首次出现在2000年Roy Fielding的博士论文中。

  1. RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中。
  2. 把后端所有的数据/文件都看成资源.,那么接口请求数据,本质上来说就是对资源的操作了.
  3. 而对于数据资源分别使用POST、DELETE、GET、UPDATE等请求动作来表达对数据的增删查改。
    在这里插入图片描述
    参考文档:https://www.runoob.com/w3cnote/restful-architecture.html

二.序列化

api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把数据转换格式,序列化可以分两个阶段:

序列化: 把我们识别的数据转换成指定的格式提供给别人。

例如:我们在django中获取到的数据默认是模型对象,但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人。

响应数据[序列化]

示例:

1.定义一个模型类:

from django.db import models

# Create your models here.

class Student(models.Model):

    name = models.CharField(max_length=32,verbose_name='姓名')
    sex = models.BooleanField(default=1,verbose_name='性别')
    age = models.IntegerField(verbose_name='年龄')
    class_null = models.CharField(max_length=5,verbose_name='班级编号')
    description = models.TextField(max_length=1000,verbose_name='个性签名')

2.创建一个序列化器类:

from rest_framework import serializers

class StudentSerializers(serializers.Serializer):

    name = serializers.CharField()
    sex = serializers.BooleanField()
    age = serializers.IntegerField()
    class_null = serializers.CharField()
    description = serializers.CharField()

3.视图函数:

from django.http import JsonResponse
from django.views import View
from student.models import Student
from testser.seaializers import StudentSerializers


# Create your views here.

class StudentView(View):

    def get(self, request):
        student_list = Student.objects.all()

        # 使用序列化器进行数据转换成列表的每一个成员为字典
        # 实例化序列化器类需要传递三个参数:
        # StudentSerializer(instance='',data='',context={})
        # 第一个参数instance:模型对象,这个参数一般用于把模型转成字典 进行序列化
        # 第二个参数data:客户提交的字典数据  这个参数一般用于把字典转成模型对象 进行校验数据和反序列化
        # 第三个参数context:视图中要发送给序列化器中使用的字典数据 路由或者视图中有些数据需要传递到序列化器内部的方法中调用 则可以用context以字典的格式传递进去
        # 额外参数:many表示instance是一个模型列表 此时序列化器在转换数据的时候可以进行循环 默认是False
        serializers = StudentSerializers(student_list, many=True)
        print(serializers.data)

        return JsonResponse(serializers.data,safe=False)
        #  如果不是字典格式就需要加一个safe=False关闭json数据的安全监测 否则会认为数据不安全

urls中:

from django.urls import path,re_path #re_path :用于正则匹配
from testser import views


urlpatterns = [
    path('student/',views.StudentView.as_view())
]

结果:
在这里插入图片描述
获取单条数据:

class StudentOneView(View):


    def get(self,request,pk):

        student_obj = Student.objects.filter(pk=pk).first()
        serializers = StudentSerializers(student_obj) # 单个对象 不再是模型列表
        print(serializers.data) #{'name': '张三', 'sex': True, 'age': 13, 'class_null': '301', 'description': 'test'}

        return JsonResponse(serializers.data)

三.反序列化

反序列化:把别人提供的数据转换/还原成我们需要的格式。

例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中。
接收数据[反序列化]

示例:

1.定义一个模型类:

class Book(models.Model):
    # 图书模型
    title = models.CharField(verbose_name='书名', max_length=30, null=True, blank=True)
    pub_data = models.DateField(verbose_name='发布日期')
    read = models.IntegerField(verbose_name='阅读量', default=0)
    comment = models.IntegerField(verbose_name='评论', null=True, blank=True)

2.定义一个序列化器:

from rest_framework import serializers


class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=30)  # 里面可以写校验规则
    pub_data = serializers.DateField(required=True)
    read = serializers.IntegerField(default=0, min_value=0)
    comment = serializers.IntegerField(allow_null=True)

3.视图函数:

from django.shortcuts import render
from .serializers import BookSerializers
from django.views import View
from django.http import JsonResponse


class BookView(View):

        def get(self, request):
        # print(json.loads(request.body)) {'title': 'python', 'pub_date': '2019-10-10', 'read': 100, 'comment': 300}

        book_dict = {
                "title":"python",
                "pub_data":"2019-10-10",
                "read":-11,
                "comment":300

            }

        # 调用序列化器类进行反序列化数据校验
        serializers = BookSerializers(data=book_dict)
        ret = serializers.is_valid()
        print('****',ret)  # True

        # 错误信息
        print(serializers.errors)
        '''
        {'read': [ErrorDetail(string='Ensure this value is greater than or equal to 0.', code='min_value')]}
        '''


        # 正确信息
        print(serializers.validated_data)
        '''
        OrderedDict([('title', 'python'), ('pub_data', datetime.date(2019, 10, 10)), ('read', 100), ('comment', 300)])
        '''
        return JsonResponse({'massage': 'ok'})

urls中:

from django.urls import path,re_path
from testunser import views

urlpatterns = [
    path('test_book/',views.BookView.as_view())
]

四.反序列化数据校验

from rest_framework import serializers

# 3.外部函数设置为验证函数
def check_title(data):

    check_field = '123'
    if check_field in data:
        raise serializers.ValidationError(f'不能包含{check_field}!!')
    '''
    {'title': [ErrorDetail(string='不能包含123!!', code='invalid')]}
    '''

class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=30,validators=[check_title])  # 里面可以写校验规则
    pub_data = serializers.DateField(required=True)
    read = serializers.IntegerField(default=0, min_value=0)
    comment = serializers.IntegerField(allow_null=True)

    # 1.单个字段校验
    def validate_title(self, attrs):

        if '789' in attrs:
            raise serializers.ValidationError('不能包含123!!!!')
        return attrs

    '''
    {'title': [ErrorDetail(string='不能包含123!!!!', code='invalid')]}
    '''

    # 2.多个字段校验
    def validate(self, attrs):
        read = attrs.get('read')
        comment = attrs.get('comment')

        if comment > read:
            raise serializers.ValidationError('评论量不能大于阅读量!!!')
        return attrs

    '''
    {'non_field_errors': [ErrorDetail(string='评论量不能大于阅读量!!!', code='invalid')]}
    '''

猜你喜欢

转载自blog.csdn.net/qq_39253370/article/details/106491783