drf安装、序列化组件

发布时间 2023-08-31 16:32:42作者: 凡人半睁眼

一、drf的安装使用

1、drf介绍

  drf全称djangorestframework,是django的一个第三方app,目的是方便我们快速实现符合restful规范的接口

2、安装使用

2.1  安装模块

djangorestframework

2.2 django 是2版本,用不了drf最新(适当降版本),会自动卸载django,装最django新版4.x

使用 djagno 3.1.12 可以使用最新版本drf

2.3 注册app(arf是第三方app)

INSTALLED_APPS = [
            'rest_framework',  
        ]

2.4  写路由

from rest_framework.routers import DefaultRouter
    router = DefaultRouter()
    router.register('books', BookView, 'books')
    
    urlpatterns += router.urls

2.5 写视图类

from rest_framework.viewsets import ModelViewSet
from .serializer import BookSerializer
    class BookView(ModelViewSet):
        queryset = Book.objects.all()
        serializer_class = BookSerializer

2.6  写序列化类

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"

二、序列化组件(重要!!)

1、序列化组件介绍

DRF的序列化组件是该框架的核心部分,用于在Django应用程序中处理复杂数据结构的序列化和反序列化

它的主要作用是在 models 和 views 视图函数之间建立桥梁,使数据能够在数据库模型和API接口之间进行转换,同时还能够进行数据验证、字段选择和数据转换。

序列化组件有以下作用:

  1. 序列化(Serialization): 序列化是将数据从复杂的数据结构(如Django模型)转换为可以在API响应中传输的格式(如JSON)。通过使用序列化器,你可以定义模型的字段,并指定哪些字段需要包含在API响应中。这样,当你从数据库中检索数据并将其传递到API响应中时,序列化器会自动将数据转换为适当的格式。

  2. 反序列化(Deserialization): 反序列化是将API请求中的数据转换为数据库模型或其他Python对象。例如,当用户通过API提交数据以创建或更新资源时,DRF的序列化器可以将传入的数据验证并将其转换为数据库模型实例,然后保存到数据库中。

  3. 数据验证和转换: 序列化组件允许你定义字段的验证规则,例如字段是否必需、数据类型是否正确以及其他自定义验证。它还允许你在保存数据之前对数据进行自定义转换,以便确保数据的一致性和准确性。

  4. 嵌套关系处理: 在复杂的数据模型中,可能存在多层嵌套的关系。序列化器允许你在API响应中嵌套关联的数据,并在API请求中处理这些嵌套的关系。

  5. 字段选择和映射: 有时候你可能只需要返回模型的部分字段,而不是全部字段。序列化器允许你选择要包含在API响应中的字段,从而减少传输的数据量。此外,它还支持字段的重命名,使API的字段名与模型的字段名可以不同。

总之,DRF的序列化组件使得在Django项目中处理复杂数据结构、数据验证和数据转换变得更加简单和灵活。通过定义序列化器,你可以更好地控制数据的输入和输出,同时提供一种清晰的方式来处理API请求和响应中的数据。

2、序列化组件的引入

2.1  新建一个py文件---> serializer.py ---> 写一个序列化类

继承drf提供的serializers.Serializer

在类中写要序列化的字段:字段类---> 跟之前学过的models.py中的字段类完全对应,但是比models多

# 写序列化类
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import User, Book

class UserSerializer(serializers.Serializer):
    # 写要序列化的字段
    # 字段限制
    name = serializers.CharField(max_length=8, min_length=3, required=True)
    hobby = serializers.CharField()
    password = serializers.CharField()
    age = serializers.IntegerField()

    # 局部钩子
    # 写一个方法  validate_字段名,传入要校验的数据--》前端传入的
    def validate_name(self, value):
        if value.startswith('sb'):
            raise ValidationError('不能以sb开头')  # 如果校验失败,抛ValidationError
        return value  # 如果校验通过,返回 value,后续继续用

    # 全局钩子
    # 名字和hobby不能一致   多个字段的同时校验
    def validate(self, attrs):  # 前端传入的所有数据,局部校验通过之后attrs 字典
        name = attrs.get('name')
        hobby = attrs.get('hobby')
        if name == hobby:
            raise ValidationError('名字和爱好不能一样')
        else:
            return attrs

    # 重写create方法
    def create(self, validated_data):  # validated_data:前端传入,校验过后的数据
        user = User.objects.create(**validated_data)
        return user

2.2 在视图类中,使用序列化类

多条:serializer=UserSerializer(instance=users,many=True)

# instance 要序列化的对象实例 (qs,单个对象)   many=True表示序列化多条,如果不写就是序列化一条

单条:serializer=UserSerializer(instance=user)

2.3 拿到序列化后的数据

serializer.data  可能是列表,可能是字典

2.4 使用drf提供的Resposne 返回

from rest_framework.response import Response

三、序列化组件快速使用之序列化

1、 路由

urlpatterns = [
    path('users/', UserView.as_view()),
    path('users/<int:pk>', UserDetailView.as_view()),
]

2、 视图类

from .models import User
from .serializer import UserSerializer
from rest_framework.response import Response

class UserView(APIView):
    def get(self,request):
        users=User.objects.all()
        # 之前用for循环,现在用序列化类
        # 传了两个参数:instance 要序列化的对象(qs,单个对象)   many=True表示序列化多条,如果不写就是序列化一条
        ser=UserSerializer(instance=users,many=True)
        # 拿到序列化后的数据  ser.data--->多条就是列表  单条字典
        return Response(ser.data)

class UserDetailView(APIView):
    def get(self,request,pk):
        user=User.objects.all().filter(pk=pk).first()
        # 传了两个参数:instance 要序列化的对象   many=True表示序列化多条
        ser=UserSerializer(instance=user)
        return Response(ser.data)

3、 序列化类 serializer.py

class UserSerializer(serializers.Serializer):
    # 写要序列化的字段
    # 字段自己
    name = serializers.CharField(max_length=8, min_length=3, required=True)
    hobby = serializers.CharField()
    password = serializers.CharField()
    age = serializers.IntegerField()

四、序列化类 serializer.py 常用字段类和参数

1、 常用字段类

# 写序列化类的时候,写了CharField,IntegerField  跟django中models中的类似
BooleanField、CharField、
IntegerField、DecimalField、
DateField、FileField

# 序列化类中的和models中的一一对应,但是序列化类中多一些

# 多的--->暂时有个印象,后面会详细讲
ListField
DictField

# 使用场景
	{name:金鹏没,price:99,publish:{name:xx出版社,addr:南京},authors:[{},{}]}

2、常用字段参数

# 字段类上,可以传参数,是做反序列化校验用的(前端拿到的数据做反序列化)        CharField:max_length,min_lenght,allow_blank: 可以不传
IntegerField:max_value,min_value
    
 # 所有字段都可以用通用的
-非常重要:read_only,write_only
-default,required,allow_null

五、序列化组件之校验

# 反序列化之校验:    ser.is_valid()
    1 字段自己的校验规则(字段类的属性上) 
    2 局部钩子(给某个字段加校验规则)  
    3 全局钩子
    
# 反序列化保存
	ser.save()---》必须序列化类中重写 create--》自己定保存到哪个表
    def create(self, validated_data):  # validated_data:前端传入,校验过后的数据
        user = User.objects.create(**validated_data)
        return user