设计一个RESTful API来与SQLite数据库交互

设计一个RESTful API来与SQLite数据库交互

在本章中,我们将为HTTP请求创建Django API视图,并将讨论Django和Django REST框架如何处理每个HTTP请求。

  • 创建Django视图
  • 将URL路由到Django视图和函数
  • 启动Django的开发服务器
  • 使用命令行工具进行HTTP请求
  • 用Postman做HTTP请求

创建Django视图

在前面的章节中,你已经看到了如何创建一个模型和它的序列化器。现在,让我们来看看如何处理HTTP请求并提供HTTP响应。在这里,我们将创建Django视图来处理HTTP请求。在收到一个HTTP请求时,Django会创建一个HttpRequest实例,并将其作为第一个参数传递给视图函数。这个实例包含有HTTP动词的元数据信息,如GET、POST或PUT。视图函数检查该值并根据HTTP动词执行代码。这里的代码使用@csrf_exempt装饰器来设置一个CSRF(跨站请求伪造)cookie。这使得测试代码更加容易,它并没有描绘出一个可用于生产的网络服务。让我们进入代码实现。

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from rest_framework import status
from taskmanagement.models import TaskManagement
from taskmanagement.serializers import TaskMngSerializer
  
  
class JSONResponse(HttpResponse):
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)
  
@csrf_exempt
def task_list(request):
    if request.method == 'GET':
        task = TaskManagement.objects.all()
        task_serializer = TaskMngSerializer(task, many=True)
        return JSONResponse(task_serializer.data)
  
    elif request.method == 'POST':
        task_data = JSONParser().parse(request)
        task_serializer = TaskMngSerializer(data=task_data)
        if task_serializer.is_valid():
            task_serializer.save()
            return JSONResponse(task_serializer.data, \
                                status=status.HTTP_201_CREATED)
        return JSONResponse(task_serializer.errors, \
                            status = status.HTTP_400_BAD_REQUEST)
              
  
@csrf_exempt
def task_detail(request, pk):
    try:
        task = TaskManagement.objects.get(pk=pk)
    except TaskManagement.DoesNotExist:
        return HttpResponse(status=status.HTTP_404_NOT_FOUND)
  
    if request.method == 'GET':
        task_serializer = TaskMngSerializer(task)
        return JSONResponse(task_serializer.data)
  
    elif request.method == 'PUT':
        task_data = JSONParser().parse(request)
        task_serializer = TaskMngSerializer(task, data=task_data)
        if task_serializer.is_valid():
            task_serializer.save()
            return JSONResponse(task_serializer.data)
        return JSONResponse(task_serializer.errors, \
                            status=status.HTTP_400_BAD_REQUESTS)
  
    elif request.method == 'DELETE':
        task.delete()
        return HttpResponse(status=status.HTTP_204_NO_CONTENT)
         

让我们评估一下这段代码。这里我们有两个函数。

  1. task_list()
  2. task_detail()

注意:以后我们将为我们的RESTFul网络服务添加安全和节流规则。而且,我们还需要删除重复的代码。现在,上述代码对于理解基本事物的运作是必要的。

task_list()

task_list()函数能够处理两个HTTP动词 – GETPOST

如果动词是GET,代码会检索所有的任务管理实例。

如果 request.method == ‘GET’:

task = TaskManagement.objects.all()

task_serializer = TaskMngSerializer(task, many=True)

return JSONResponse(task_serializer.data)

  • 它使用TaskManagement.objects.all()方法检索所有任务。
  • 使用TaskMngSerializer(task, many=True)将任务序列化。
  • TaskMngSerializer生成的数据被传递给JSONResponse ,并且
  • 返回建立的JSONResponse。

注意: TaskMngSerializer(task, many=True)中的many=True参数指定多个实例必须被序列化。

如果动词是POST,代码会创建一个新的任务。在这里,新任务在HTTP请求的主体中以JSON数据的形式提供。

elif request.method == ‘POST’:

task_data = JSONParser().parse(request)

task_serializer = TaskMngSerializer(data=task_data)

if task_serializer.is_valid():

task_serializer.save()

return JSONResponse(task_serializer.data, \

status=status.HTTP_201_CREATED)

return JSONResponse(task_serializer.errors, \

status = status.HTTP_400_BAD_REQUEST)

  • 使用JSONParser来解析该请求。
  • 使用TaskMngSerializer,将解析的数据序列化。
  • 如果数据是有效的,它将被保存在数据库中,并且
  • 返回构建的JSONResponse(包含数据和HTTP_201_CREATED状态)。

task_detail()

task_detail()函数能够处理三种HTTP动词–GET、PUT和DELETE。在这里,该函数接收主键作为参数,并对具有相同键的特定实例进行相应的操作。

如果动词是GET,那么代码会根据键来检索一个任务。如果动词是PUT,那么代码会更新实例并将其保存到数据库中。如果动词是DELETE,那么代码会根据pk值将实例从数据库中删除。

JSONResponse()

除了解释的两个函数外,代码中还有一个名为JSONResponse的类。

class JSONResponse(HttpResponse): 

def __init__(self, data, **kwargs): 

content = JSONRenderer().render(data) 

kwargs[‘content_type’] = ‘application/json’ 

super(JSONResponse, self).__init__(content, **kwargs) 

它将数据渲染成JSON格式,并将返回的字节字符串保存在content局部变量中。

将URL路由到Django视图和函数

现在,有必要将URLs路由到视图。你需要在任务管理文件夹(restapi\taskmanagement)中创建一个新的Python文件,名为urls.py,并添加以下代码。

from django.conf.urls import url
from taskmanagement import views
  
urlpatterns = [
    url(r'^taskmanagement/',views.task_list),
    url(r'^taskmanagement/(?P<pk>[0-9]+)', views.task_detail),
]

基于匹配的正则表达式,URL被路由到相应的视图。接下来,我们必须替换restapi文件夹中urls.py文件的代码(restapi\restapi\urls.py)。目前,它有根URL的配置。用下面的代码更新urls.py文件。

from django.conf.urls import url, include
  
urlpatterns = [
    url(r'^',include('taskmanagement.urls')), 
]

启动Django的开发服务器

激活虚拟环境后,你可以运行以下命令来启动服务器。

python manage.py runserver

分享下面的截图。

设计一个RESTful API来与SQLite数据库交互

Development server

使用命令行工具进行HTTP请求

让我们利用我们在第一章中安装的命令行工具。

HTTP GET请求

HTTP GET请求是用来从数据库中检索任务的细节。我们可以使用GET请求来检索一个任务集合或一个单一任务。

检索所有元素

下面的curl命令检索了一个任务的集合。

curl -X GET localhost:8000/taskmanagement/

输出:

设计一个RESTful API来与SQLite数据库交互

在执行命令时,Django会创建一个HttpRequest实例,并将其作为第一个参数传递给视图函数。Django将该URL路由到相应的视图函数中。这里的视图有两个方法,task_list和task_detail。让我们来看看URL模式,它是在taskmanagement\urls.py文件中配置的

urlpatterns = [ 

url(r’^taskmanagement/’,views.task_list), 

url(r’^taskmanagement/(?P<pk>[0-9]+)’, views.task_detail), 

] 

这里的URL(localhost:8000/taskmanagement/)与views.task_list的URL模式相匹配。_task_list方法__被执行并检查HTTP动词。由于我们请求的HTTP动词是GET,它检索了所有的任务。

让我们运行命令,通过结合-i和-X选项来检索所有的任务。这里的好处是,它显示了HTTP响应头、状态、内容-类型等。

curl -iX GET localhost:8000/taskmanagement/

输出:

设计一个RESTful API来与SQLite数据库交互

到目前为止,我们已经执行了cURL命令。现在,我们将看看HTTPie实用程序命令,以编写和发送HTTP请求。为此,我们需要访问安装在虚拟环境中的HTTPie工具提示。激活虚拟环境后,运行下面的命令。

http :8000/taskmanagement/

该命令发送了请求。GET http://localhost:8000/taskmanagement/。

输出:

设计一个RESTful API来与SQLite数据库交互

HTTPie实用GET请求 – 检索所有任务

检索单一元素

现在你已经熟悉了检索任务集合的命令。接下来,让我们了解如何根据任务ID检索任务。在这里,我们将把任务ID与URL一起传递。由于URL有一个参数,Django将URL路由到task_detail函数。让我们来执行这些命令。

HTTPie实用程序命令来检索一个单一的任务。

http :8000/taskmanagement/2

上述命令发送了请求。GET http://localhost:8000/taskmanagement/2。

输出:

设计一个RESTful API来与SQLite数据库交互

使用HTTPie工具检索单个元素

相等的curl命令如下。

curl -iX GET localhost:8000/taskmanagement/2

输出:

设计一个RESTful API来与SQLite数据库交互

让我们尝试检索一个不在数据库中的元素。

 http :8000/taskmanagement/5

输出如下

HTTP/1.1 404 Not Found
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Fri, 30 Oct 2020 14:32:46 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

HTTP POST请求

我们使用POST请求来创建一个任务。用HTTPUtilityPie命令来创建一个新的请求,如下所示。

http POST :8000/taskmanagement/ task_name=”Document XYZ” task_desc=”Document Description” category=”Writing” priority=”Low” created_date=”2020-10-30 00:00:00.000000+00:00″ deadline=”2020-11-03 00:00:00.000000+00:00″ status=”Pending” payment_done=false

这里的URL请求(http POST :8000/taskmanagement/)与正则表达式(taskmanagement/$)匹配。因此,它调用了函数task_list,,POST动词满足了执行任务创建代码的条件。

输出:

设计一个RESTful API来与SQLite数据库交互

使用HTTPUtilityPie的POST请求

让我们用curl命令创建另一个实例。用于POST请求的curl命令如下

curl -iX POST -H “Content-Type: application/json” -d “{\”task_name\”:\”Task 01\”, \”task_desc\”:\”Desc 01\”, \”category\”:\”Writing\”, \”priority\”:\”Medium\”, \”created_date\”:\”2020-10-27 13:02:20.890678\”, \”deadline\”:\”2020-10-29 00:00:00.000000+00:00\”, \”status\”:\”Completed\”, \”payment_done\”: \”true\”}” localhost:8000/taskmanagement/

输出:

设计一个RESTful API来与SQLite数据库交互

使用curl的POST请求

在这里,创建一个新任务所需的数据被指定在-d之后,使用-H “Content-Type: application/json”表示数据是JSON格式。

{

“task_name”:”Task 01″, “task_desc”:”Desc 01″, “category”:”Writing”, “priority”:”Medium”, “created_date”:”2020-10-27 13:02:20.890678″, “deadline”:”2020-10-29 00:00:00.000000+00:00″, “status”:”Completed”, “payment_done”: “true”

}

HTTP PUT请求

我们利用PUT请求来更新一个现有的任务。在这里,我们把需要更新的任务的ID和URL一起传递给对方。由于URL有一个参数,Django将URL实例发送到视图中的task_detail函数。并且,执行持有PUT动词条件的代码。

更新任务的HTTPie实用命令。

http PUT :8000/taskmanagement/1 task_name=”Swap two elements” task_desc=”Write a Python program to swap two elements in a list” category=”Writing” priority=”Medium” created_date=”2020-10-27 13:02:20.890678″ deadline=”2020-10-29 00:00:00.000000+00:00″ status=”Completed” payment_done=true

输出:

设计一个RESTful API来与SQLite数据库交互

PUT

相等的CURL命令如下

curl -iX PUT -H “Content-Type: application/json” -d “{\”task_name\”:\”Swap two elements\”, \”task_desc\”:\”Write a Python program to swap two elements in a list\”, \”category\”:\”Writing\”, \”priority\”:\”Medium\”, \”created_date\”:\”2020-10-27 13:02:20.890678\”, \”deadline\”:\”2020-10-29 00:00:00.000000+00:00\”, \”status\”:\”Completed\”, \”payment_done\”: \”true\”}” localhost:8000/taskmanagement/1

HTTP DELETE请求

HTTP DELETE请求是用来从数据库中删除一个特定的任务。让我们来看看HTTPie实用命令。

http DELETE :8000/taskmanagement/4

输出:

设计一个RESTful API来与SQLite数据库交互

Delete Request

相等的curl命令如下。

curl -iX DELETE localhost:8000/taskmanagement/4

用Postman做HTTP请求

到目前为止,我们利用了命令行工具来编写和发送HTTP请求。现在,我们将使用Postman。Postman REST客户端是一个图形用户界面(GUI)工具,它可以方便地编写和发送HTTP请求到Django开发服务器。让我们来编写和发送GET和POST请求。

GET Request

你可以在下拉菜单中选择GET,在URL栏中输入URL ( localhost:8000/taskmanagement/ ),然后点击发送按钮。Postman将在输出Body部分显示信息。下面的屏幕截图显示了JSON输出响应。

设计一个RESTful API来与SQLite数据库交互

使用Postman的HTTP GET请求

你可以点击 “页眉 “标签,查看页眉的详细信息。分享下面的屏幕截图。

设计一个RESTful API来与SQLite数据库交互

Header

POST Request

现在让我们使用Postman GUI工具发送一个POST请求。按照下面的步骤进行。

1.从下拉菜单中选择POST动词。
2.在URL字段中输入URL ( localhost:8000/taskmanagement/ )
3.选择车身部分(在输入部分)。
4.勾选原始单选按钮,同时在GraphQL按钮右侧的下拉菜单中选择JSON。
5.输入以下几行{“task_name”: “Task 01”, “task_desc”: “Desc 01”, “category”: “Writing”, “priority”: “Medium”, “created_date”: “2020-11-02 13:02:20.890678”, “deadline”: “2020-10-29 00:00.000000+00:00”, “status”: “Completed”, “payment_done”:”true”}在正文中(输入部分)。并点击发送。

分享下面的截图。

设计一个RESTful API来与SQLite数据库交互

Summary

在这篇文章中,我们为HTTP请求创建了一个Django API视图,通过RESTFul网络服务与SQLite数据库进行交互。我们使用了GET、POST、PUT和DELETE等HTTP动词。我们已经看到了如何使用命令行工具(curl和HTTPie)和GUI工具(POSTMAN)来发送和编写HTTP请求。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程