drf-restful规范

发布时间 2023-08-29 21:11:25作者: Way*yy

RESTful API规范

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

"""
	RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中。
"""

这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源。

1、数据安全的保障

url链接一般使用https协议进行传输,因为https协议比http协议更安全

2、接口特征表现

用api关键字标识接口url:url中含有api关键字的:
	# https://api.baidu.com/books
	# https://www.baidu.com/api/books

3、多数据版本共存

在url链接中标识数据的版本:
    # https://api.baidu.com/v1/books
    # https://www.baidu.com/api/v2/books
url中的v1、v2就是不同数据的版本体现

4、数据既是资源,均使用名词(可复数)

1、接口一般都是完成前后端数据交互的,交互的数据我们一般称之为资源:
	# https://api.baidu.com/v1/books
    
2、一般提倡用资源的复数形式,在url链接中奖励不要出现操作资源的动词,
	错误示范:# https://api.baidu.com/delete-user

3、特殊的接口可以出现动词:
    # https://api.baidu.com/login
    # https://api.baidu.com/register

5、资源操作由请求的方式来决定(method)

一般来说操作资源都会涉及到增删查改,所以我们使用请求方式来表示增删查改
    # https://api.baidu.com/books		----->get请求,获取所有书籍
    # https://api.baidu.com/books/1		----->get请求,获取主键为1的书籍
    # https://api.baidu.com/books		----->post请求,添加一本书籍
    # https://api.baidu.com/books/1		----->put请求,修改主键为1的书籍
    # https://api.baidu.com/books/1		----->delete请求,删除主键为1的书籍

6、过滤,通过在url上传参的形式传递搜索条件

只针对于搜索所有接口:
    https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
    https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
    https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
    https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
    https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

7、响应状态码(两层)

http协议:第一层
	1XX,2XX,3XX,4XX,5XX
后端返回的状态码:第二层
	{
        "code": 200, "msg": "登录成功", "date": []
    },
	{
        "code": 1002, "msg": "请求失败"
    }
1、正常响应状态码2XX:
    200:常规请求成功
    201:创建成功
2、重定向响应状态码3XX:
    301:永久重定向
    302:暂时重定向
3、客户端异常响应状态码4XX:
    403:请求无权限
    404:请求路径不存在
    405:请求方法不存在
4、服务器异常响应状态码5XX:
    500:服务器异常

8、错误处理,应返回错误信息,error当key

{
    error:"无权限操作"
}

9、返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范

GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档

10、需要url请求的资源需要访问资源的请求链接

{
  	"status": 0,
  	"msg": "ok",
  	"results":[
        {
            "name":"肯德基(罗餐厅)",
            "img": "https://image.baidu.com/kfc/001.png"
        }
      	...
		]
}
 # 响应中带链接:"img": "https://image.baidu.com/kfc/001.png"

序列化

api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把数据转换格式,序列化可以分两个阶段:
	序列化:通俗的讲序列化就是把我们自己的数据转换成json格式的数据,可以供其他语言接收使用
    反序列化:通俗的说就是将别人序列化好的json格式的数据拿过来,我通过反序列化成我自己的数据类型,然后使用
eg:
    python:{"name":"yang","age":"18"}	-----序列化----->	前端JS	
    前端JS	----->反序列化----->	前端中JS的对象:{"name":"yang","age":"18"}

drf的安装以及快速使用

1、安装drf:
	pip install djangorestframework 或者直接在pycharm中搜索djangorestframework安装
    注意事项:
        1、解释器最低版本以及Django最低版本:Python 3.6+、Django 4.2, 4.1, 4.0, 3.2, 3.1, 3.0
        2、如果Django版本不符合drf的安装条件,就会自动将Django卸载并且自动安装最新版本的Django
2、在App中注册:
    INSTALLED_APPS = [
        'rest_framework',  # 一定要加
    ]
3、写路由
	from app_one import views
    from rest_framework.routers import DefaultRouter

    router = DefaultRouter()
    router.register("books", views.BookView, "books")
    urlpatterns += router.urls

4、写视图类
    from rest_framework.viewsets import ModelViewSet
    from .serializers import BookSerializers


    class BookView(ModelViewSet):
        queryset = models.Books.objects.all()
        serializer_class = BookSerializers
5、写序列化
    5.1、先创建一个serializers.py文件
    5.2、写序列化类
        from rest_framework import serializers
        from .models import Books


        class BookSerializers(serializers.ModelSerializer):
            class Meta:
                model = Books
                fields = "__all__"	

作业

# 1 基于原生django,写book的5个接口
    from django.http import JsonResponse
    from app_one import models
    from django.views import View
    import json
	class MybookViews(View):
        def get(self, request):
            book_obj = models.Books.objects.filter(is_delete=1).all()
            book_list = []
            for book in book_obj:
                book_list.append({"book_name": book.book_name, "book_price": book.book_price})
            return JsonResponse({"code": 200, "msg": "查找成功", "date": book_list})

        def post(self, request):
            book_name = request.POST.get("book_name")
            book_price = request.POST.get("book_price")
            models.Books.objects.create(book_name=book_name, book_price=book_price)
            return JsonResponse(
                {"code": 200, "msg": "添加成功", "data": {"book_name": book_name, "book_price": book_price}})


    class MybookDetail(View):
        def get(self, request, pk):
            try:
                book_obj = models.Books.objects.filter(pk=pk, is_delete=1).first()
            except:
                return JsonResponse({"code": 101, "msg": "该书籍不存在"})
            return JsonResponse({"code": 200, "msg": "查找成功",
                                 "data": [{"book_name": book_obj.book_name, "book_price": book_obj.book_price}]})

        def put(self, request, pk):
            book_dic = json.loads(request.body)
            book_name = book_dic.get("book_name")
            book_price = book_dic.get("book_price")
            models.Books.objects.filter(pk=pk).update(book_name=book_name, book_price=book_price)
            return JsonResponse(
                {"code": 200, "msg": "修改成功",
                 "data": [{"code": 20, "msg": "修改成功", "data": [{"book_name": book_name, "book_price": book_price}]}]})

        def delete(self, request, pk):
            models.Books.objects.filter(pk=pk).update(is_delete=0)
            return JsonResponse({})
       
        
# 拓展:
	-mysql:char 和varchar
    	2、MySQL中char和varchar的区别:
        2.1、长度是否可变
            varchar 类型的长度是可变的,而 char 类型的长度是固定的
            char 类型是一个定长的字段,以 char(10) 为例,不管真实的存储内容多大或者是占了多少空间,都会消耗掉 10 个字符的空间
            通俗来讲,当定义为 char(10) 时,即使插入的内容是 'abc' 3 个字符,它依然会占用 10 个字节,其中包含了 7 个空字节
            varchar类型就是你存几个字符就占用几个字符的空间,不会浪费资源
        2.2、存储长度
            char 长度最大为 255 个字符,varchar 长度最大为 65535 个字符
        2.3、检索效率方面
            varchar 类型的查找效率比较低,而 char 类型的查找效率比较高
    -mysql--->int类型--->int(10),int(20)
        int(10)的意思是假设有一个变量名为id,它的能显示的宽度能显示10位。在使用id时,假如我给id输入10,那么mysql会默认给你存储0000000010。当你输入的数据不足10位时,会自动帮你补全位数。假如我设计的id字段是int(20),那么我在给id输入10时,mysql会自动补全18个0,补到20位为止。

request.body

request.body:
    	当使用 HTTP 协议进行通信时,请求主体(request body)是包含发送给服务器的数据的部分。它通常用于在 POST、PUT 和 PATCH 请求中发送表单数据、JSON 数据或其他类型的数据。

request.POST和request.body

request.POST与request.body:
  django中的request.POST只能取到Content-Type(请求头)为application/x-www-form-urlencoded(form表单默认格式)的数据,如果请求头为application/json(json格式),multipart/form-data(文件)等格式无法取到,只有在request.body里面能取到原生的数据。当发送过来的是JSON数据是,request.POST取到的数据是空的,这时只有用request.body取,再反序列化才能使用。