美文网首页
接口开发_Django REST framework

接口开发_Django REST framework

作者: tzktzk1 | 来源:发表于2023-12-03 20:11 被阅读0次

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)

相关文章

网友评论

      本文标题:接口开发_Django REST framework

      本文链接:https://www.haomeiwen.com/subject/gfflgdtx.html