使用Django开发REST接口
我们以在Django框架中使用的图书以及书中人物案例来写一套支持图书数据增删改查的REST API接口,来理解REST API的开发(前后端均发送JSON格式数据)
路由代码(urls.py):
urlpatterns = [ path('books/', views.BookListView.as_view()), re_path('books/(?P<pk>d+)/', views.BookDetailView.as_view()) ]
views.py:
from datetime import datetime from django.http import JsonResponse,HttpResponse import json class BookListView(View): """ 查询所有的书籍、增加书籍 """ def get(self,request): """ 查询所有的书籍, 路由:GET /books/ :param request: :return: """ queryset = BookInfo.objects.all() book_list = [] for book in queryset: book_list.append({ "id":book.id, "btitle":book.title, "bpub_date":book.pub_date, "bread":book.read, "bcommet":book.comment, "image":book.image.url if book.image else "" }) #为了不使字典的数据发送,将参数safe变为False return JsonResponse(book_list,safe=False) def post(self,request): """ 新增书籍 路由:POST/books/ :param request: :return: """ json_bytes = request.body json_str = json_bytes.decode() #将字符串对象反序列化 book_dict = json.loads(json_str) ################################ book = BookInfo.objects.create( title = book_dict.get("btitle"), pub_date = book_dict.get("bpub_date") #.....................省略其他参数 ) #返回插入的数据,以json格式返回,并且带上状态码 return JsonResponse({ "id":book.id, "btitle":book.title, 'bpub_date': book.pub_date, 'bread': book.read, 'bcomment': book.comment, 'image': book.image.url if book.image else '' },status=201) class BookDetailView(View): def get(self,request,pk): """ 获取单个图书信息 路由:GET/books/<pk>/ :param request: :param pk: :return: """ try: book = BookInfo.objects.get(pk=pk) except BookInfo.DoesNotExist: return HttpResponse(status=404) return JsonResponse({ "id": book.id, "btitle": book.title, 'bpub_date': book.pub_date, 'bread': book.read, 'bcomment': book.comment, 'image': book.image.url if book.image else '' }) def put(self,request,pk): """ 修改图书信息 路由:PUT/books/<pk>/ :param request: :param pk: :return: """ try: book = BookInfo.objects.get(pk=pk) except BookInfo.DoesNotExist: return HttpResponse(status=404) json_bytes = request.body json_str = json_bytes.decode() book_dict = json.loads(json_str) ##########此处详细的校验参数省略############# book.title = book_dict.get('btitle') book.pub_date = book_dict.get('bpub_date') book.save() return JsonResponse({ "id": book.id, "btitle": book.title, 'bpub_date': book.pub_date, 'bread': book.read, 'bcomment': book.comment, 'image': book.image.url if book.image else '' }) def delete(self,request,pk): """ 删除图书 路由:DELETE/books/<pk>/ :param request: :param pk: :return: """ try: book = BookInfo.objects.get(pk=pk) except BookInfo.DoesNotExist: return HttpResponse(status=404) book.delete() return HttpResponse(status=204)
测试:
使用Postman软件测试接口
1、获取所有图书信息
GET方式访问http://127.0.0.1:8000/books/,返回状态码200以及json数据
2、获取单一的图书数据
GET 访问 http://127.0.0.1:8000/books/5/ ,返回状态码200以及json数据
3、新增书籍信息
POST访问http://127.0.0.1:8000/books/,发送json数据,返回json数据以及状态码
4、修改书籍数据
PUT访问http://127.0.0.1:8000/books/2/,发送json数据,返回json数据以及状态码
5、删除书籍数据
DELETE访问http://127.0.0.1:8000/books/2/,发送json数据,返回状态码204
2、明确REST接口开发的核心任务
在上面的案例中,在开发REST API接口时候,视图主要做的三件事:
1、将请求的数据(如json格式)转化为模型类对象
2、操作数据库(增删改查)
3、将模型类对象转换为响应的数据(如json数据格式)
序列化(Serialization)
就是将程序中的一个数据结构类型转化为其他格式(字典、json、XML等)。例如在Django中的模型类对象转换为JSON字符串,这就是序列化(json.dumps())。
反之,将其他数据(字典、json、XML等)转化为程序的数据,例如将JSON字符串转换为Django中的模型类对象,这个过程就叫反序列化(json.load())
在开发REST API时,视图中要频繁的进行序列化与反序列化。
总结:
在开发REST API接口,在视图中需要做的核心就是:1、将数据库数据序列化(json.dumps())为前端所需要的格式,并返回。2、将前端发送的数据反序列化(json.load())为模型类对象,保存在数据库中。
Django REST framework介绍:
在序列化与反序列化时,虽然操作的数据不尽相同,但是执行的过程却是相似的,也就是说这部分代码是可以复用简化编写的。
在开发REST API的视图中,虽然每个视图具体操作的数据不同,但增、删、改、查的实现流程基本套路化,所以这部分代码也是可以复用简化编写的:
- 增:校验请求数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
- 删:判断要删除的数据是否存在 -> 执行数据库删除
- 改:判断要修改的数据是否存在 -> 校验请求的数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
- 查:查询数据库 -> 将数据序列化并返回
Django REST framework可以帮助我们简化上述两部分的代码编写,大大提高REST API的开发速度。Django REST framework 框架是一个用于构建Web API 的强大而又灵活的工具。通常简称为DRF框架 或 REST framework。DRF框架是建立在Django框架基础之上,由Tom Christie大牛二次开发的开源项目。
特点
- 提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;
- 提供了丰富的类视图、Mixin扩展类,简化视图的编写;
- 丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;
- 多种身份认证和权限认证方式的支持;
- 内置了限流系统;
- 直观的 API web 界面;
- 可扩展性,插件丰富