在这里插入图片描述

1. RESTFul API 接口需求及设计

本文以学生信息查询功能为例,采用前后端分离架构,要求后端提供RESTFul 接口。

1.1 本例要求提供如下查询功能:

  • 列表查询、单条查询
  • 添加学生信息
  • 更改学生信息
  • 删除学生信息

1.2 数据库student表结构如下:

字段类型长度说明
namestring30学生姓名
nostring10学号
gendertiny int10: 男, 1: 女
ageint4年龄
class_namestring30班级名称
scoreint4成绩

1.3 按REST接口指导原则, RESTFul 风格API 设计如下

在开始之前,推荐阅读 REST接口基本原理

操作请求类型资源请求url请求数据
列表查询GEThttp://127.0.0.1:8000/student/
单条查询GEThttp://127.0.0.1:8000/student/<int:id>/
添加记录POSThttp://127.0.0.1:8000/student/{‘name’:‘Jack’, ‘no’:‘A001’,…}
更改记录PUThttp://127.0.0.1:8000/student/<int:id>/{‘name’:‘Jack’, ‘no’:‘B001’,…}
删除记录DELETEhttp://127.0.0.1:8000/student/<int:id>/

注意,RESTFul风格url 不需要在 url中添加操作动词,如 http://127.0.0.1:8000/student/list/。 当然这样做也可以,只是推荐方式更简洁。

2. 为什么使用Django-rest-framework来开发RESTful API?

Django 是最流行的Python Web开发框架,本身提供了ORM 数据库封装、模板、视图、路由、权限与鉴权, 管理后台等完整的工具链,各种功能开箱即用。 django-rest-framework (简称DRF) 继承了django框架的上述优点,开发与部署不需要第3方库的支持就可以轻松完成数据库CRUD的 REST API开发,并提供完善的鉴权、分级权限控制、测试页面等功能,可以快速地开发出一套高质量的REST API。

其它的框架,如 Flask-Rest,实际应用时,还需要集成数据接口库、鉴权、权限管理等第3方库来完成,测试也需要第3方工具支持,在集成配置,代码质量控制上,难度显然增大了,最终投入成本往往超过django-rest-framework。当然如果你是有经验的Flask开发人员则另当别论。

3. 创建django 项目

3.1 安装 django-rest-framework

创建与激活虚拟环境

python3 -m venv env_rest
cd env_rest
.\script\activate   # 激活虚拟环境

pip install django
pip install djangorestframework

在linux下激活虚拟环境命令为

source env_test/bin/activate 

安装django-rest-framework

pip install django
pip install djangorestframework

3.2 创建django 项目与应用

新建1个项目

django-admin startproject RestTutorial

在RestTutorial 项目下,新建1个app

cd RestTutorial
python manage.py startapp student_rest

3.3 修改全局配置

打开RestTutorial/RestTutorial/settings.py 文件,添加以下配置

INSTALLED_APPS = [
    ...
    'rest_framework',   # 导入DRF库
    ‘student_rest’,    # 导入新建app
]

# 设置分页器
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}


将语言与时区修改为中国的

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = False

3.4 准备model

django默认使用sqlite3 数据库, 你可以将数据库后端 改为mysql, postgreSql 等你熟悉的数据库,细节略过。

**定义Student Model **

打开文件 RestTutorial/student_rest/models.py, 输入以下代码

from django.db import models
from django.urls import reverse


# 学生信息model 定义
class Student(models.Model):
    name = models.CharField(max_length=30,verbose_name="姓名")
    no = models.CharField(max_length=10,verbose_name="学号")    
    gender = models.IntegerField(max_length=10,verbose_name="性别")
    age = models.IntegerField(verbose_name="年龄")
    class_name = models.CharField(max_length=30,verbose_name="班级")
    score = models.IntegerField(verbose_name="成绩")

    def __str__(self) -> str:
        return self.name

    class Meta:
        db_table = "student"
        managed = True
        verbose_name = "学生表"
        verbose_name_plural = verbose_name
        unique_together = ['no']

模型定义好以后,需要更新数据库。

python manage.py makemigrations
python manage.py migrate  

3.5 将 Student 模型加入到管理后台

为了添加数据方便,可以将新建的model 添加到django管理后台,添加初始数据更加方便

打开 RestTutorial/student_rest/admins.py 文件,添加如下代码

from django.contrib import admin
from .models import *

# Register your models here.

class StudentAdmin(admin.ModelAdmin):
    list_display = ['id','name','no','gender','age','class_name','score']
    list_per_page = 10
    
admin.site.register(Student, StudentAdmin)   

3.6 启动项目,添加初始数据

创建1个管理员帐号,并启动项目:

python manage.py createsuperuser 
python manage.py runserver 0.0.0.0:8000

如下出现如下信息,就表示运行成功

System check identified 1 issue (0 silenced).
July 06, 2023 - 13:52:06
Django version 3.2.8, using settings 'RestTutorial.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CTRL-BREAK.

打开浏览器,输入 http://127.0.0.1:8000/admin/ ,登录后,进入管理后台。

打开学生表,添加初始数据,
在这里插入图片描述

4. DRF编程实现RESTful 接口

DRF 编程很关键的一步是定义Serializer 类,用于将 model 数据序列化。其使用方式与django Form 表单非常相似。
DRF 视图可采用函数式编程,或Class Based View(CBV)视图类的方式编程,并且DRF内置了各种通用视图类来简化编程。

4.1 自定义Serializer 类

新建文件: tutorial/student_rest/serializers.py,, 输入以下代码

from rest_framework import serializers
from .models import Student


class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = "__all__"

4.2 用函数式编程实现视图功能

DRF对视图编程,提供了@api_view() 装饰器来实现函数式编程,通常响应仅提供Json字节串,不提供DRF特有的接口测试页面功能。
打开 RestTutorial/student_rest/views.py, 文件,输出以下代码

from django.shortcuts import render
from django.http import JsonResponse, HttpResponse
from rest_framework.parsers import JSONParser
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view
from rest_framework import status
from .models import Student
from .serializers import StudentSerializer


# Create your views here.

# @csrf_exempt
@api_view(['GET','POST'])
def student_list(request):
    if request.method == 'GET':
        # 获取所有数据步骤: 1.获取数据 2.序列化 3.用json格式发送数据
        qs = Student.objects.all()
        serilizer = StudentSerializer(qs, many=True)
        print(serilizer.data)
        return JsonResponse(serilizer.data, safe=False)
    elif request.method =='POST':
        # 新增一条数据的步骤: 1.获取数据 2.反序列化 3.保存至数据库 4.发送结果 
        data = JSONParser().parse(request)
        serilizer = StudentSerializer(data=data)
        if serilizer.is_valid():
            serilizer.save()
            return JsonResponse(serilizer.data, status=status.HTTP_201_CREATED)
        return JsonResponse(serilizer.errors, status=status.HTTP_400_BAD_REQUEST)

def student_detail(request,pk):
    # retrieve, update or delete a row of student model 
    
    # 读取单条数据
    try: 
        row = Student.objects.get(pk=pk)
    except Student.DoesNotExist:
        return HttpResponse(status=status.HTTP_404_NOT_FOUND)
    
    if request.method == 'GET':
        serializer = StudentSerializer(row)
        return JsonResponse(serializer.data)
    elif request.method == 'PUT':
        input_data = JSONParser().parse(request)
        serializer = StudentSerializer(row, data=input_data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=status.HTTP_200_OK)
    elif request.method == 'DELETE':
        row.delete()
        return HttpResponse(status=status.HTTP_204_NO_CONTENT)

打开 tutorial/student_rest/urls.py, 输入


from django.urls import path
from student_rest import views, views_cbv


urlpatterns = [
    path('v1/', views.student_list),             # 用于函数式View测试, list, create
    path('v1/<int:pk>/', views.student_detail),  # 用于函数式View测试, retrieve, update, delete

]

url中加入了v1/主要是为了与下一章CBV视图类路由做个区分。
在打开项目的路由本置文件 RestTutorial/RestTutorial/urls.py, 加入一条路由

from django.contrib import admin
from django.urls import path,include
from student_rest import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('student/', include('student_rest.urls')),
]

4.3 运行并验证

运行项目,
python manage.py runserver 0.0.0.0:8000

前面提到过, 函数式编程不提供测试界面,因此测试接口需要使用第3方工具。
由于浏览器无法发送 post, put, delete消息, 因此建议使用postman 或 curl 等工具来测试
打开postman, 查询所有记录:GET http://127.0.0.1:8000/student/v1/,
在这里插入图片描述
测试 添加数据的接口: POST http://127.0.0.1:8000/student/v1/
注意, body 选择raw, json, 手工输入要添加的数据,json格式。
在这里插入图片描述
再用list 接口查询,可以看到数据已添加成功。

5. 使用视图类实现REST API

DRF的函数式编程,相对于其它编程语言已经非常简便了。 但前一章可以看出,post, put 实际上还要做校验与保存等工作,delete要做删除等动作,实际应用时可能更多。如果有多个模式,每个类都要写重复语句。为节省这些精力,DRF提供了视图类,混入类来帮助简化编程,同时还提供了测试界面的功能。

5.1 CBV 视图类实现代码

下面我们新建1个文件 RestTutorial/student_rest/views_cbv.py, 输入以下代码

from django.shortcuts import render
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Student
from .serializers import StudentSerializer
from rest_framework import generics
from rest_framework.permissions import IsAdminUser

class StudentList(generics.ListCreateAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

class StudentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

非常简洁地就实现了第4章的全部功能。 下面为新的视图类添加路由;
打开 tutorial/student_rest/urls.py, 添加

    path("v2/", views_cbv.StudentList.as_view()), # 用于Class-based View测试, list, create
    path("v2/<int:pk>/", views_cbv.StudentDetail.as_view()), # 用于Class-based View测试, retrieve, update, delete

5.2 验证

再次运行项目, 这次不需要第3方工具,就可以进行完整测试
json 格式:
http://127.0.0.1:8000/student/v2.json
或者:
http://127.0.0.1:8000/student/v2?format=json

内置视图类也提供了html格式的响应,查看与测试接口更方便:
http://127.0.0.1:8000/student/v2/
页面显示如下:在这里插入图片描述
页面最下方提供了添加学习数据的post接口测试功能。

再打开detail view 页面,如http://127.0.0.1:8000/student/v2/6/, 页面如下:
在这里插入图片描述
页面下方,是 PUT更改数据的测试接口,上方有delete 按钮,用于测试delete 接口。 接口数据显示也非常友好,也便于前端开发人员阅读。

对于较正式的项目,本人推荐使用django test模块,编写自动化测试脚本,也不需要selenium等第3方测试工具支持。

总结

使用 django-rest-framework 开发基于数据库CRUD的 REST API, 提供完整的内置工具箱,便得整个开发以及测试过程方便快捷,同时,django提供了强大的扩展功能,对于项目的后期扩展、维护也带来了便利。
因此,使用 django-rest-framework 框架进行REST API开发,是中小项目非常不错的选择。

完整项目代码: 点击下载

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐