一、Restful API

可以总结为一句话,REST是所有Web应用都应该遵守的架构设计指导原则,面向资源是REST最明显的特征

1.1、设计规范

资源

统一接口

url

无状态

这里着重说一下无状态,什么是无状态,即所有资源都可以通过URL定位,而且这个定位与其他的资源无关,也不会因为其他资源的变化而变化。

1.2、Http常用动词

GET 从服务器获取资源

POST 在服务器创建资源或者更新资源

PUT 更新资源(客户端提供改变后所有资源)

PATCH 更新资源 (客户端提供改变的属性)

DELETE 删除资源

HEAD 获取数据的元数据

OPTIONS 获取信息

1.3、网络请求状态码

2开头 (请求成功)表示成功处理了请求的状态代码。

200   (成功)  服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 
201   (已创建)  请求成功并且服务器创建了新的资源。 
202   (已接受)  服务器已接受请求,但尚未处理。 
203   (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。 
204   (无内容)  服务器成功处理了请求,但没有返回任何内容。 
205   (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206   (部分内容)  服务器成功处理了部分 GET 请求。

3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

300   (多种选择)针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 
301   (永久移动)请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302   (临时移动)服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303   (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304   (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。 
305   (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。 
307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。

400   (错误请求) 服务器不理解请求的语法。 
401   (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 
403   (禁止) 服务器拒绝请求。
404   (未找到) 服务器找不到请求的网页。
405   (方法禁用) 禁用请求中指定的方法。 
406   (不接受) 无法使用请求的内容特性响应请求的网页。 
407   (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408   (请求超时)  服务器等候请求时发生超时。 
409   (冲突)  服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 
410   (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。 
411   (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 
412   (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 
413   (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 
414   (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 
415   (不支持的媒体类型) 请求的格式不受请求页面的支持。 
416   (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 
417   (未满足期望值) 服务器未满足"期望"请求标头字段的要求。

5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

500   (服务器内部错误)  服务器遇到错误,无法完成请求。 
501   (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 
502   (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 
503   (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 
504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。 
505   (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

二、Django Rest Framework

这个软件包可以在Django的基础上迅速实现API,用以构建WEB API,并且自身还带有WEB的测试页面,方便测试自己的API。

官方文档

https://q1mi.github.io/Django-REST-framework-documentation/

安装

pip install djangorestframework
2.1、序列化

序列化可以把查询集和模型对象转换为json、xml或其他类型,也提供反序列化功能,也就是把转换后的类型转换为对象或查询集。

REST框架中的序列化程序与Django Form 和 ModelForm 类的⼯作⽅式⾮常相似。官方提供了⼀个 Serializer 类,它为您提供了⼀种强⼤的通⽤⽅法来控制响应的输出,以及⼀个 ModelSerializer 类,它提供了⼀个有⽤的快捷⽅式来创建处理模型实例和查询集的序列化程序。

2.1.1、声明序列化器

app/my_serializer.py

from rest_framework import serializers

class StudentsSerializer(serializers.Serializer):
    stu_num = serializers.CharField()
    stu_name = serializers.CharField()
    stu_gender = serializers.CharField()
2.1.2、常用fileld类

核心参数

参数名缺省值说明
read_onlyFalse只允许序列化输出
requiredTrue反序列化必须存在该字段
default缺省值
allow_nullFalse是否允许传入NULL
validators[]函数列表验证器
error_messages{}一个错误信息字典

常用字段

字段名说明
BooleanField对应于django.db.models.fields.BooleanField
CharFieldmax_length - 验证输⼊包含的字符数不超过此数量。
min_length - 验证输⼊包含不少于此数量的字符。
allow_blank- 如果设置为True则空字符串视为有效值。如果设置为False则空字符串报错,默认为False。
trim_whitespace- 如果设置为True则会修剪前导和尾随空格。默认为True
EmailFieldEmailField(max_length=None, min_length=None, allow_blank=False)
IntegerFieldmax_value 验证提供的数字是否不⼤于此值。
min_value 验证提供的数字是否不低于此值。
FloatFieldmax_value 验证提供的数字是否不⼤于此值。
min_value 验证提供的数字是否不低于此值。
DateTimeFieldformat - 格式字符串可以是显式指定格式的Python strftime格式
input_formats - 表示可⽤于解析⽇期的输⼊格式的字符串列表
2.1.3、创建serializer对象

定义好Serializer类后,就可以创建Serializer对象了。Serializer的构造⽅法为

Serializer(instance=None, data=empty, **kwarg)

1) ⽤于序列化时,将模型类对象传⼊instance参数
2) ⽤于反序列化时,将要被反序列化的数据传⼊data参数
3) 除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如

serializer = UserSerializer(User, context={'request': request})
2.1.4、序列化实例

settings.py

INSTALLED_APPS = [
    'rest_framework',
]

models.py

class Students(models.Model):
    username = models.CharField(max_length=20)
    password = models.CharField(max_length=20)

    class Meta:
        db_table = 'user'

my_serializer.py

from rest_framework import serializers

class StudentsSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

views.py

class sertest(APIView):
    def get(self, request):
        stu = Students.objects.all().first()
        ser = StudentsSerializer(instance=stu)
        return Response(ser.data)

我们在我们的前端页面可以得到结果

{
    "username": "tom",
    "password": "123"
}
2.2、反向序列化

使⽤序列化器进⾏反序列化时,需要对数据进⾏验证后,才能获取验证成功的数据或保存成模型类对象。在获取反序列化的数据前,必须调⽤is_valid()⽅法进⾏验证,验证成功返回True,否则返回False。

验证失败,可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误。如果是⾮字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。

验证成功,可以通过序列化器对象的validated_data属性获取数据。在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是⼀种验证⾏为。

2.2.1、单字段验证
validate_<field_name>(self, value)
2.2.2、多字段验证
validate(self, attrs):
2.2.3、实例

my_serializer.py

class StudentsSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validated_username(self, value):
        if value[0] == '_':
            raise serializers.ValidationError('不允许下划线开头')
        return value

    def validate(self, attrs):
        username = attrs['username']
        password = attrs['password']
        if len(username) > len(password):
            raise serializers.ValidationError('密码长度过短')
        return attrs

views.py

class sertest(APIView):
    def post(self, request):
        data = request.POST
        ser = StudentsSerializer(data=data)
        print(ser.is_valid())
        return Response({'code': 200})

我们POSTMAN发送请求,发现反悔了我们希望的数据,而且serializer的数据为True,也就是数据通过了验证

2.2.4、保存

如果在验证成功后,想要基于validated_data完成数据对象的创建,可以通过实现create()和update()两个⽅法来实现。

my_serializer.py

class StudentsSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validated_username(self, value):
        if value[0] == '_':
            raise serializers.ValidationError('不允许下划线开头')
        return value

    def validate(self, attrs):
        username = attrs['username']
        password = attrs['password']
        if len(username) > len(password):
            raise serializers.ValidationError('密码长度过短')
        return attrs

    def create(self, validated_data):
        return Students.objects.create(**validated_data)

    def update(self, instance, validated_data):
        '''instance 为要更新的对象实例'''
        instance.username = validated_data.get('username')
        instance.password = validated_data.get('password')
        instance.save()
        return instance

views.py

保存

class sertest(APIView):
    def post(self, request):
        data = request.POST
        ser = StudentsSerializer(data=data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 200})
        return Response({'code': 400})

更新

class sertest(APIView):
    def post(self, request):
        data = request.POST
        stu = Students.objects.get(username=data.get('username'))
        # 更新和直接保存的区别在于这里我们还需要传入我们需要更新的Query
        ser = StudentsSerializer(data=data, instance=stu)
        if ser.is_valid():
            ser.save()
            return Response({'code': 200})
        return Response({'code': 400})
2.3、ModelSerializer

ModelSerializer类能够让你⾃动创建⼀个具有模型中相应字段的Serializer类。这个ModelSerializer类和常规的Serializer类⼀样,不同的是:

它根据模型⾃动⽣成⼀组字段。

它⾃动⽣成序列化器的验证器,⽐如unique_together验证器。

它默认简单实现了.create()⽅法和.update()⽅法。

my_serializer.py

class StudentsSerializer(serializers.ModelSerializer):
	class Meta:
		model = Students
		# 包含模型中所有字段
		field = '__all__'
        # 包含模型中指定字段
        fields = ('username', 'password')
        # 排除模型中指定字段,这里需要注意,即使是排除一个字段,也需要加逗号,因为是一个迭代器
        exclude = ('username',)
        # 指明只读字段
        read_only_fields = ('username',)
        # 添加额外参数
        extra_kwargs = {
            'bread': {'min_value': 0, 'required': True},
			'bcomment': {'min_value': 0, 'required': True},
        }

三、Request和Response

3.1、Request

REST框架引⼊了⼀个扩展了常规HttpRequest的Request对象,并提供了更灵活的请求解析。Request对象的核⼼功能是request.data属性,它与request.POST类似,但对于使⽤Web API更为有⽤。REST framework 提供了Parser解析器,在接收到请求后会⾃动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进⾏parse解析,解析为类字典对象保存到Request对象中。Request对象的数据是⾃动根据前端发送数据的格式进⾏解析之后的结果。⽆论前端发送的哪种格式的数据,我们都可以以统⼀的⽅式读取数据。

3.1.1、data属性

request.data 返回解析之后的请求体数据。类似于Django中标准的
request.POST 和 request.FILES 属性,但提供如下特性:

包含了解析之后的⽂件和⾮⽂件数据
包含了对POST、PUT、PATCH请求⽅式解析后的数据
利⽤了REST framework的parsers解析器,不仅⽀持表单类型数据,也⽀持JSON数据

request.POST 只适⽤于’POST’⽅法。request.data 处理任意数据,适⽤于’POST’,'PUT’和’PATCH’⽅法

3.1.2、query_params 查询参数

request.query_params 与Django标准的 request.GET 相同,只是更换了更正确的名称⽽已。

3.1.3、method

request.method 返回请求的HTTP⽅法的 ⼤写字符串表示形式。

3.2、Response

REST framework提供了⼀个响应类 Response ,使⽤该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。

Response(data, status=None, template_name=None, headers=None, content_type=None)
参数说明:
data: 为响应准备的序列化处理后的数据;
status: 状态码,默认200;
template_name: 模板名称,如果使⽤HTMLRenderer 时需指明;
headers: ⽤于存放响应头信息的字典;
content_type: 响应数据的Content-Type,通常此参数⽆需传递,REST framework会根据前端所需类型数据来设置该参数。

四、wrapping

这种方式可以帮助我们用函数的方式写视图

⽤于基于函数视图的@api_view装饰器。⽤于基于类视图的APIView类。

from rest_framework.decorators import api_view

@api_view(['GET', 'POST']) 
def snippet_list(request):
	pass

其实学到这里我们已经基本掌握了怎么返回一个序列化的数据以及怎么处理一个序列化的数据,下面的基于CBV的操作只是在很大程度上方便我们的操作而已。

五、基于类的视图CBV

REST framework 提供了众多的通⽤视图基类与扩展类,以简化视图的编写。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7kilcl0z-1645102778685)(\image-24162874681234687.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sCNLcdsM-1645102778686)(\image-87243978127349.png)]

5.1、APIView

APIView是DRF的基类,它⽀持GET POST PUT DELETE等请求类型,且各种类型的请求之间,有了更好的分离在进⾏dispatch分发之前,会对请求进⾏身份认证,权限检查,流量控制。继承⾃Django的 View ⽗类。 APIView 与 View 的不同之处在于

传⼊到视图⽅法中的是REST framework的 Request 对象,⽽不是Django的HttpRequeset 对象;
视图⽅法可以返回REST framework的 Response 对象,视图会为响应数据设置(render)符合前端要求的格式;
任何 APIException 异常都会被捕获到,并且处理成合适的响应信息;
在进⾏dispatch()分发前,会对请求进⾏身份认证、权限检查、流量控制。

支持定义的属性

authentication_classes 列表或元组,身份认证类

permissoin_classes 列表或元祖,权限检查类

throttle_classes 列表或元祖,流量控制类

5.2、mixins

使⽤基于类的视图的⼀个最⼤的好处就是我们可以灵活的选择各种View,使我们的开发更加的简洁。mixins⾥⾯对应了ListModelMixin,CreateModelMixin, RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin。

视图⽅法可以返回REST framework的 Response 对象,视图会为响应数据设置(render)符合前端要求的格式;
任何 APIException 异常都会被捕获到,并且处理成合适的响应信息;
在进⾏dispatch()分发前,会对请求进⾏身份认证、权限检查、流量控制。

支持定义的属性

authentication_classes 列表或元组,身份认证类

permissoin_classes 列表或元祖,权限检查类

throttle_classes 列表或元祖,流量控制类

5.2、mixins

使⽤基于类的视图的⼀个最⼤的好处就是我们可以灵活的选择各种View,使我们的开发更加的简洁。mixins⾥⾯对应了ListModelMixin,CreateModelMixin, RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐