万事开头难

rest_framework:序列化器类/视图

一.序列化器类

序列化就是把数据转换为json 在服务端发送到客户端
反序列化是客户端法的数据发送到服务端 服务端通过反序列化把数据转换为json

from rest_framework import serializers

serializers 是dfr提供给开发者调用的序列化模块 里面声明了所有可用序列化器的基类

serializer 序列化基类 drf中所有的序列化器类都必须继承serializer

ModelSerializer  模型序列化器类 是序列化的子类 在工作中 除了serializer基类以外 最常用的序列化类基类 

1).serializer

1.1转换的字段说明(序列化)

先在应用下创建序列化器文件 然后在文件中:
class Serializer1(serializers.Serializer):
    # 1.转换的字段声明(把数据放到序列化器中就会转换为对应的类型)
    # 格式: 字段 = serializers.字段类型(选项=选项值)
    id = serializers.IntegerField()
    title = serializers.CharField()
  
serializers.py
urlpatterns = [
    path('BookView/', views.BookView.as_view()),
]
urls.py
 1 from seriali.serializers import Serializer1
 2 from django.views import View
 3 from django.http.response import JsonResponse
 4 from app01.models import Book
 5 
 6 
 7 class BookView(View):
 8     def get(self,request):
 9         """序列化器-序列化阶段的调用"""
10         # 1.获取数据集 并把数据放到序列化器中
11         book_list = Book.objects.filter()
12         # print(book_list.title)
13         #2. 实例化序列化器 得到序列化方法 
14         # 注意!!!: 传递到序列化器的模型对象如果是多个,务必使用many = True 如果是单独的比如 Book.objects.filter() 可以不加many=True
15         serializer = Serializer1(instance=book_list,many=True)
16         #3. 调用序列化器对象的data方法 这个方法会获取转换后的数据
17         data = serializer.data
18         return JsonResponse(data=data,status=201,safe=False)
Views.py

1.2转换的字段说明(反序列化)

class Serializer(serializers.Serializer):
    # 1.转换的字段声明
    # 比如id字段需要转换为json就可以写上
    # 格式: 字段 = serializers.字段类型(选项=选项值)
    id = serializers.IntegerField(read_only=True,max_value=100,min_value=0,error_messages={"max_value":"最大值为100"})
    # read_only=True 在客户端提交数据[反序列化阶段不会要求id字段] max_value=100表示值最大为一百 min_value=0表示值最小为0
    title = serializers.CharField(required=True)    # required=True  反序列化阶段必须
    state = serializers.BooleanField(default=True)  # default=True   反序列化阶段 客户端没有填写 默认为True
    pub_date = serializers.CharField(allow_blank=True,allow_null=True) # 允许客户端不填写内容(none) 或者值为""
serializers.py
urls.py
    def get(self,request):
        # 反序列化数据--采用字段选项来验证数据
        # 1.接受客户端提交的数据
        args = json.loads(request.body.decode())
        print(args)
        # 1.1. 实例化序列化器 获取序列化对象
        serializer = Serializer(data=args)
        # 1.2  调用序列化器进行数据验证
        # raise_exception=True表示如果有异常直接抛出 代码不会往下执行
        ret = serializer.is_valid(raise_exception=True) #ret返回True表示成功 如果返回False表示失败
        # 1.3  获取验证后的结果
        if ret:
            print(serializer.validated_data) #serializer.validated_data 获取反序列化后的结果
        else:
            print(serializer.errors) # serializer.errors 获取异常数据结果
        # 2. 操作数据库
        # pass


        # 3. 返回结果
        return JsonResponse(data={}, status=201, safe=False)
views.py

 1.3验证代码的对象方法

如果需要对一些字段和数据进行复杂的校验一共有两种方式
#格式是validate_字段名称
    def validate_title(self,data):
        # 第一种 单独校验一个字段 格式 def validate_字段(self,data):
        print("正在校验title",data)
        if data in ["python","吴鸿昌"]:
            raise serializers.ValidationError(detail="包含敏感字符",code="name")
        return data
第一种 单独校验一个字段
def validate(self,attrs):
       print(attrs["title"],"这是")
       return attrs

# attrs表示所有字段 必须要这样写
第二种 校验所有

1.4模型操作的方法

如果在实例化序列化器时,传入instance表示更新数据 否则表示添加数据
    def create(self,validate_data):
        """
        添加数据 函数名必须叫create  参数validate_data也是固定的
        :param validate_data: 表示验证以后的结果
        :return:
        """
        data = Book.objects.create(**validate_data)
        print("过来了数据")
        return data
serializers.py#添加数据
    def get3(self,request):
        # 反序列化数据--采用字段选项来验证数据
        # 1.接受客户端提交的数据
        args = json.loads(request.body.decode())
        print(args,"看看数据")
        # 1.1. 实例化序列化器 获取序列化对象
        serializer = Serializer(data=args)
        # 1.2  调用序列化器进行数据验证
        # raise_exception=True表示如果有异常直接抛出 代码不会往下执行
        serializer.is_valid(raise_exception=True) #ret返回True表示成功 如果返回False表示失败
        serializer.save()   # 写入数据
        # 3. 返回结果
        return JsonResponse(data={}, status=201, safe=False)
views.py#添加数据
    def update(self,instance,validate_data):
        """
        更新数据 方法名固定
        :param instance:实例化序列化器对象时,必须传入的模型对象
        :param validate_data: 验证成功以后的数据
        :return:
        """
        instance.title = validate_data["title"]
        instance.save()

        return validate_data
serializers.py #更新数据
    def get(self,request):
        # 更新数据 要先获取更新哪一条数据 也就是pk值
        # urls.py: path("seriali/(?P<pk>\d+)/",views.BookView.as_view())
        # 1.获取pk的值
        pk=1 # 比如
        book = Book.objects.get(pk=pk)
        # 2.获取要修改的值
        args = json.loads(request.body.decode())

        # 3.修改操作中的实例化序列化器对象
        serializer = Serializer(instance=book,data=args)

        # 4.验证数据
        serializer.is_valid(raise_exception=True)
        # 存数据
        serializer.save()

        return JsonResponse(serializer.data, status=201, safe=False)
views.py#更新数据

 2).modelserializers

相对于父类(serializers),modelserializer自动实现了以下三个步骤:

  1. 可以根据指定的model自动检测并自动序列化的字段,不需要提前定义
  2. 自动为序列化生成校验器
  3. 自动实现了create()和update()

serializer的属性和方法:

1.save()
在调用serializer.save()时,会创建或者更新一个Model实例(调用create()或update()创建),具体根据序列化类的实现而定,如:

2.create()、update()
Serializer中的create()和update()方法用于创建生成一个Model实例,在使用Serializer时,如果要保存反序列化后的实例到数据库,则必须要实现这两方法之一,生成的实例则作为save()返回值返回。方法属性validated_data表示校验的传入数据,可以在自己定义的序列化类中重写这两个方法。

3. is_valid()
当反序列化时,在调用Serializer.save()之前必须要使用is_valid()方法进行校验,如果校验成功返回True,失败则返回False,同时会将错误信息保存到serializer.errors属性中。

4.data
serializer.data中保存了序列化后的数据。

5.errors
当serializer.is_valid()进行校验后,如果校验失败,则将错误信息保存到serializer.errors属性中。

serializer的Field:

1.CharField
对应models.CharField,同时如果指定长度,还会负责校验文本长度。

max_length:最大长度;
min_length:最小长度;
allow_blank=True:表示允许将空串做为有效值,默认False;

2.EmailField
对应models.EmailField,验证是否是有效email地址。

3.IntegerField
对应models.IntegerField,代表整数类型

4.FloatField
对应models.FloatField,代表浮点数类型

5.DateTimeField
对应models.DateTimeField,代表时间和日期类型。

format='YYYY-MM-DD hh:mm':指定datetime输出格式,默认为DATETIME_FORMAT值。
需要注意,如果在 ModelSerializer 和HyperlinkedModelSerializer中如果models.DateTimeField带有auto_now=True或者auto_add_now=True,则对应的serializers.DateTimeField中将默认使用属性read_only=True,如果不想使用此行为,需要显示对该字段进行声明:

    class CommentSerializer(serializers.ModelSerializer):
        created = serializers.DateTimeField()
     
        class Meta:
            model = Comment
        
6.FileField
对应models.FileField,代表一个文件,负责文件校验。

max_length:文件名最大长度;
allow_empty_file:是否允许为空文件;

7.ImageField
对应models.ImageField,代表一个图片,负责校验图片格式是否正确。

max_length:图片名最大长度;
allow_empty_file:是否允许为空文件;
如果要进行图片处理,推荐安装Pillow: pip install Pillow

8.HiddenField
这是serializers中特有的Field,它不根据用户提交获取值,而是从默认值或可调用的值中获取其值。一种常见的使用场景就是在Model中存在user_id作为外键,在用户提交时,不允许提交user_id,但user_id在定义Model时又是必须字段,这种情况下就可以使用HiddenField提供一个默认值:

    class LeavingMessageSerializer(serializers.Serializer):
        user = serializers.HiddenField(
            default=serializers.CurrentUserDefault()
        )

 

serializer的公共参数:

所谓公共参数,是指对于所有的serializers.<FieldName>都可以接受的参数。以下是常见的一些公共参数。

1.read_only
    read_only=True表示该字段为只读字段,即对应字段只用于序列化时(输出),而在反序列化时(创建对象)不使用该字段。默认值为False。

2.write_only
    write_only=True表示该字段为只写字段,和read_only相反,即对应字段只用于更新或创建新的Model时,而在序列化时不使用,即不会输出给用户。默认值为False。

3.required
    required=False表示对应字段在反序列化时是非必需的。在正常情况下,如果反序列化时缺少字段,则会抛出异常。默认值为True。

4.default
    给字段指定一个默认值。需要注意,如果字段设置了default,则隐式地表示该字段已包含required=False,如果同时指定default和required,则会抛出异常。

5.allow_null
    allow_null=True表示在序列化时允许None作为有效值。需要注意,如果没有显式使用default参数,则当指定allow_null=True时,在序列化过程中将会默认default=None,但并不会在反序列化时也默认。

6.validators
    一个应用于传入字段的验证函数列表,如果验证失败,会引发验证错误,否则直接是返回,用于验证字段,如:

    username = serializers.CharField(max_length=16, required=True, label='用户名',
                                    validators=[validators.UniqueValidator(queryset=User.objects.all(),message='用户已经存在')]) 

7.error_message
    验证时错误码和错误信息的一个dict,可以指定一些验证字段时的错误信息,如:

    mobile= serializers.CharField(max_length=4, required=True, write_only=True, min_length=4,
                                 label='电话', error_messages={
                                    'blank': '请输入验证码',
                                    'required': '该字段必填项',
                                    'max_length': '验证码格式错误',
                                    'min_length': '验证码格式错误',
                                })
7.style
    一个键值对,用于控制字段如何渲染,最常用于对密码进行密文输入,如:

    password = serializers.CharField(max_length=16, min_length=6, required=True, label='密码',
                                    error_messages={
                                        'blank': '请输入密码',
                                        'required': '该字段必填',
                                        'max_length': '密码长度不超过16',
                                        'min_length': '密码长度不小于6',
 
                                    },
                                    style={'input_type': 'password'}, write_only=True) 
9.label
    一个简短的文本字串,用来描述该字段。

10.help_text
    一个文本字串,可用作HTML表单字段或其他描述性元素中字段的描述。

11.allow_blank
    allow_blank=True 可以为空    设置False则不能为空

12.source
    source='user.email'(user表的email字段的值给这值)  设置字段值  类似default   通常这个值有外键关联属性可以用source设置

13.validators
    验证该字段跟  单独的validate很像

    UniqueValidator 单独唯一

    validators=[UniqueValidator(queryset=UserProfile.objects.all())

    UniqueTogetherValidator: 多字段联合唯一,这个时候就不能单独作用于某个字段,我们在Meta中设置。

    validators = [UniqueTogetherValidator(queryset=UserFav.objects.all(),fields=('user', 'course'),message='已经收藏')]

14.error_messages
    错误消息提示

    error_messages={
        "min_value": "商品数量不能小于一",
        "required": "请选择购买数量"
    })
7.ModelSerializers
    ModelSerializers继承于Serializer,相比其父类,ModelSerializer自动实现了以下三个步骤:

    1.根据指定的Model自动检测并生成序列化的字段,不需要提前定义;
    2.自动为序列化生成校验器;
    3.自动实现了create()方法和update()方法。
    使用ModelSerializer方式如下:

    class StudentSerializer(serializers.ModelSerializer):
        class Meta:
            # 指定一个Model,自动检测序列化的字段
            model = StudentSerializer
            fields = ('id', 'name', 'age', 'birthday')
相比于Serializer,可以说是简单了不少,当然,有时根据项目要求,可能也会在ModelSerializer中显示声明字段,这些在后面总结。

model
该属性指定一个Model类,ModelSerializer会根据提供的Model类自动检测出需要序列化的字段。默认情况下,所有Model类中的字段将会映射到ModelSerializer类中相应的字段。

二.视图

1).两个视图基类

1.APIView

APIview是drf提供的所有视图的基类,继承的是Django的view
APIview和view不同处:
 1.传到视图的方法是drf对象,而不是Django的Httprequeset对象
 2.视图方法可以返回drf的Response对象,视图会为响应数据设置 符合前端期望要求的格式 
 3.django的view所有异常都会以html格式显示 apiview会自动根据客户端的accept进行错误信息的格式转换
 4.重新声明了一个新的as_view方法并在dispaych()进行路由分发前,会对请求的客户端进行身份认证,权限检查,流量控制

 操作:

from rest_framework import serializers


from app01.models import Book
class ApiSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields= "__all__"



    def validate_title(self,data):
        print("data",data)
        if data == "go2":
            raise serializers.ValidationError(detail="包含敏感字符", code="name")
        return data
serializers.py
import json

from rest_framework import status
from django.shortcuts import render
from rest_framework.views import APIView
from app01.models import Book
from demo.serailizers import ApiSerializers
from rest_framework.response import Response


# Create your views here.


class demo(APIView):
    def get(self,request):
        """获取所有数据信息"""
        # 1.获取所有书籍
        book = Book.objects.all()
        # 2.实例化序列化器
        serializers = ApiSerializers(instance=book,many=True)
        # serializers.is_valid()
        # 3.获取结果
        data = serializers.data
        # 4.返回书籍信息
        return Response(data=data,status=201)

    def post(self,request):
        """添加一条数据"""
        # 1.获取数据 并且实例化序列化器
        serializers = ApiSerializers(data=request.data)
        state = serializers.is_valid(raise_exception=True)
        if state:
            serializers.save()
            return Response(data={"msg":"ok"}, status=201)
        else:
            return Response(data=serializers.errors)


class Demo(APIView):

    def get(self,request,pk):
        """获取单挑数据"""
        try:
            data = Book.objects.get(pk=pk)
        except:
            Response(status=status.HTTP_404_NOT_FOUND)

        # 序列化
        serializers = ApiSerializers(instance=data)

        return Response(serializers.data,status=201)

    def put(self,request,pk):
        """更新一条数据"""
        # 1.获取要修改的pk值
        try:
            data = Book.objects.get(pk=pk)
        except:
            Response(status=status.HTTP_404_NOT_FOUND)

        # 2.查询出要改的值
        serializers = ApiSerializers(instance=data,data=request.data)
        # 3.反序列化
        serializers.is_valid(raise_exception=True)
        serializers.save()

        # 4.返回结果
        return Response(serializers.data,status=status.HTTP_200_OK)


    def delete(self,request,pk):
        """删除一条数据"""
        pass
views.py
"""drf URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include,re_path
from demo import views

urlpatterns = [
    path('demo/', views.demo.as_view()),
    re_path('^demo/(?P<pk>\d+)$',views.Demo.as_view())

]
urls.py

2.GenericAPIView

resr_framework.generics.GenericAPIview

继承APIview,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类提供方法支持,通常在使用时,可搭配一个或多个Mixin扩展类

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

posted @ 2022-08-26 13:51  Bo7-w  阅读(40)  评论(0编辑  收藏  举报