美文网首页
接口开发_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