Django REST framework(以下简称 DRF或REST框架)是一个开源的 Django 扩展,提供了便捷的REST API 开发框架,拥有以下特性:
- 直观的 API web 界面。
- 多种身份认证和权限认证方式的支持。
- 内置了 OAuth1 和 OAuth2 的支持。
- 内置了限流系统。
- 根据 Django ORM 或者其它库自动序列化。
- 丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要。
- 可扩展性,插件丰富。
- 广泛使用,文档丰富。
安装djangorestframework
pip install djangorestframework
配置djangorestframework
# autotpsite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # 注册 djangorestframework
'sqtp',
]
djangorestframework运行原理
30C34697541A7AE711797D656B3347F1.png
相比于原生django开发的web应用,多了一层序列化器(Serializer),如果用过Django表单(Form),应该会对其原理有所了解,序列化器和表单都是基于Field进行字段验证,而Field都来自于rest_framework.fields模块,相当于把django封装了一层。
DRF基本组件-Serializer
序列化(Serializer)是 DRF 的核心概念,提供了数据的验证和渲染功能,其工作方式类似于 Django Form
Serializer的作用是实现序列化和反序列化
所谓序列化就是将python数据对象转化成方便传输的文本格式,如:json/xml等
反序列化就是将这个过程反过来。
和models类似,序列化通常定义在应用程序下单独文件中serializer.py
如果采用了DRF模式开发django,那么model将直接和serializer交互。
模型的元数据
指的是“除了字段外的所有内容”,例如排序方式、数据库表名、人类可读的单数或者复数名等等。所有的这些都是非必须的,甚至元数据本身对模型也是非必须的。但是,我要说但是,有些元数据选项能给予你极大的帮助,在实际使用中具有重要的作用,是实际应用的‘必须’。
想在模型中增加元数据,方法很简单,在模型类中添加一个子类,名字是固定的 Meta ,然后在这个Meta类下面增加各种元数据选项或者说设置项。参考下面的例子:
from django.db import models
class Request(models.Model):
...
class Meta: # 模型元类的作用:为模型增加额外的信息,如模型对应表名,
ordering = ['id'] # 数据根据ID排序
db_table = ['reqquest'] # 模型对应的数据库表名,不设置则默认为app名_模型名
序列化类
新建序列化类 serializers.py
from rest_framework import serializers
from sqtp.models import Step, Request
class RequestSerializer(serializers.Serializer):
method_choices = ( # method可选字段,二维元组
(0, 'GET'), # 参数1:保存在数据库中的值,参数2:对外显示的值
(1, 'POST'),
(2, 'PUT'),
(3, 'DELETE'),
)
step = serializers.RelatedField(queryset=Step.objects.all(),allow_null=True)
method = serializers.ChoiceField(choices=method_choices, default=0)
url = serializers.CharField()
params = serializers.JSONField(allow_null=True)
headers = serializers.JSONField(allow_null=True)
cookies = serializers.JSONField(allow_null=True)
data = serializers.JSONField(allow_null=True)
json = serializers.JSONField(allow_null=True)
def create(self, validated_data):
"""
根据提供的验证过的数据创建并返回一个新的`Snippet`实例。
"""
return Request.objects.create(**validated_data) # 解包操作,相当于 name='case001',base_url='http://localhost'
def update(self, instance, validated_data):
"""
根据提供的验证过的数据创建并返回一个新的`Snippet`实例。
"""
instance.step =validated_data.get('step',instance.step)
instance.method =validated_data.get('method',instance.method)
instance.url =validated_data.get('url',instance.url)
instance.params =validated_data.get('params',instance.params)
instance.headers =validated_data.get('headers',instance.headers)
instance.cookies =validated_data.get('cookies',instance.cookies)
instance.data =validated_data.get('data',instance.data)
instance.json =validated_data.get('json',instance.json)
可以简写
# 序列化器作用是 转化json为模型对象数据,或者转化模型对象数据为Json
# 序列化器是针对数据模型,一个序列化器对应一个模型
from rest_framework import serializers
from sqtp.models import Step, Request
#命名规范:模型名+Serializer
class RequestSerializer(serializers.ModelSerializer):
class Meta:
model = Request #指定序列器对应的模型
# fields =['step','method','url','params','headers'] # 指定序列化模型中的字段
fields = '__all__' #序列化所有字段
使用序列化类
新建测试文件 test_serializers.py
from django.test import TestCase
from sqtp.models import Step, Request
from sqtp.serializers import RequestSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
import io
class TestRequestSerializer(TestCase):
req1 = Request.objects.create(method=1,url='/mgr/teacher1/',data={"name":"小刚","age":18,"address":"beijing"})
# 序列化1:数据对象转化成python原生数据类型
req1_serializer = RequestSerializer(req1)
print(req1_serializer.data) # 序列化后的数据存储于序列化对象的data属性中
# 序列化2: python原生数据类型转化为Json
content =JSONRenderer().render(req1_serializer.data)
print(content)
# 反序列化1: 将数据流解析为Python原生数据类型
steam = io.BytesIO(content) #构建一个steam流
data = JSONParser().parse(steam) # 转化成python原生数据类型
print(data)
# 反序列化2: python原生数据转化成模型对象实例
serializer = RequestSerializer(data=data) #构建序列化器
if serializer.is_valid(): #校验入参是否合法
print(serializer.validated_data) # 校验之后的数据
serializer.save() # 保存数据对象
# 序列化器返回完整结果集
serializer = RequestSerializer(Request.objects.all(),many=True)
print(serializer.data)
# 序列化器内部代码
print(repr(serializer))
执行测试
python manage.py test sqtp.test_serializers
DRF实践--视图编写
接口开发本质上是处理请求和响应,包括了处理请求参数,判断请求方法,处理响应字段,响应码等,本身是个枯燥的活,DRF框架为你提供自动处理这些枯燥工具的方法。先来看第一个工具,函数视图装饰器@api_view
该装饰器的作用是 确保你在视图中接收到 Request 实例,并将上下文添加到Response ,以便可以执行内容协商。
包装器还提供了诸如在适当时候返回 405 Method Not Allowed 响应,并处理在使用格式错误的输入来访问 request.data 时发生的任何 ParseError 异常。
views.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from sqtp.models import Request
from sqtp.serializers import RequestSerializer
@api_view(['GET', 'POST'])
def request_list(request):
if request.method == 'GET':
requests = Request.objects.all()
# 获取序列化器--针对当前数据模型的所有数据
serializer = RequestSerializer(requests, many=True)
print(request.data)
# 返回Json格式响应
# return JsonResponse(data=serializer.data,safe=False) #safe=False是为了支持字典以外的python对象转化成json
return Response(serializer.data)
elif request.method == 'POST':
serializer = RequestSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=status.HTTP_201_CREATED)
return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET'])
def request_detail(request, _id, format=None):
try:
req_obj = Request.objects.get(id=_id)
except Request.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = RequestSerializer(req_obj)
return Response(serializer.data)
urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('sqtp.urls')),
]
sqtp/urls.py
from django.urls import path
from sqtp import views
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
path("requests/", views.request_list),
path("requests/<int:_id>", views.request_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns) # 重写路由
启动server服务并测试
python manage.py runserver
浏览器访问:
http://127.0.0.1:8000/requests/ 或 http://127.0.0.1:8000/requests/2.json
查看对应数据
其中数字代表对应数据的ID
image.png
附录
可用的Meta选项:模型 Meta 选项 | Django 文档 | Django (djangoproject.com)
网友评论