设计一个 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。这使得测试代码变得更容易,这并不描绘生产就绪的 Web 服务。让我们进入代码实现。
Python3
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)
Python3
from django.conf.urls import url
from taskmanagement import views
urlpatterns = [
url(r'^taskmanagement/$',views.task_list),
url(r'^taskmanagement/(?P[0-9]+)$', views.task_detail),
]
Python3
from django.conf.urls import url, include
urlpatterns = [
url(r'^',include('taskmanagement.urls')),
]
让我们评估一下代码。这里我们有两个函数。
- 任务列表()
- 任务细节()
注意:稍后我们将为 RESTFul Web 服务添加安全和限制规则。而且,我们还需要删除重复的代码。现在需要上面的代码来理解基本的东西是如何工作的。
任务列表()
task_list()函数能够处理两个 HTTP 动词 – GET和POST 。
如果动词是GET ,则代码检索所有任务管理实例。
if 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()函数能够处理三个 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 视图和函数
现在,有必要路由要查看的 URL。您需要在 taskmanagement 文件夹( restapi\taskmanagement )中创建一个新的Python文件urls.py并添加以下代码。
蟒蛇3
from django.conf.urls import url
from taskmanagement import views
urlpatterns = [
url(r'^taskmanagement/$',views.task_list),
url(r'^taskmanagement/(?P[0-9]+)$', views.task_detail),
]
基于匹配的正则表达式,URL 被路由到相应的视图。接下来,我们必须替换 restapi 文件夹( restapi\restapi\urls.py )中urls.py文件中的代码。目前,它具有根 URL 配置。使用以下代码更新urls.py文件。
蟒蛇3
from django.conf.urls import url, include
urlpatterns = [
url(r'^',include('taskmanagement.urls')),
]
启动 Django 的开发服务器
激活虚拟环境后,您可以运行以下命令来启动服务器。
python manage.py runserver
下面分享截图。
使用命令行工具发出 HTTP 请求
让我们使用我们在第 1 章中安装的命令行工具。
HTTP GET 请求
HTTP GET 请求用于从数据库中检索任务详细信息。我们可以使用 GET 请求来检索任务集合或单个任务。
检索所有元素
下面的 curl 命令检索任务集合。
curl -X GET localhost:8000/taskmanagement/
输出:
在执行命令时,Django 创建一个 HttpRequest 实例,并将其作为第一个参数传递给视图函数。 Django 将 URL 路由到适当的视图函数。这里的视图有两个方法,task_list 和 task_detail。让我们看看在taskmanagement\urls.py文件中配置的 URL 模式
urlpatterns = [
url(r’^taskmanagement/$’,views.task_list),
url(r’^taskmanagement/(?P
]
这里的 URL ( localhost:8000/taskmanagement/ ) 匹配views.task_list的 URL 模式。吨他task_list方法 被执行并检查 HTTP 动词。由于我们用于请求的 HTTP 动词是GET ,因此它会检索所有任务。
让我们通过组合 -i 和 -X 选项运行命令以检索所有任务。这里的好处是它显示了 HTTP 响应头、状态、内容类型等。
curl -iX GET localhost:8000/taskmanagement/
输出:
到目前为止,我们已经执行了 cURL 命令。现在我们将看看 HTTPie 实用程序命令来编写和发送 HTTP 请求。为此,我们需要访问安装在虚拟环境中的 HTTPie 实用程序提示。激活虚拟环境后,运行以下命令。
http :8000/taskmanagement/
该命令发送请求:GET http://localhost:8000/taskmanagement/。
输出:
检索单个元素
现在您已经熟悉了检索任务集合的命令。接下来,让我们了解如何根据任务 id 检索任务。在这里,我们将传递任务 ID 和 URL。由于 URL 有一个参数,Django 将 URL 路由到 task_detail函数。让我们执行命令。
用于检索单个任务的 HTTPie 实用程序命令。
http :8000/taskmanagement/2
上述命令发送请求:GET http://localhost:8000/taskmanagement/2。
输出:
等效的 curl 命令如下:
curl -iX GET localhost:8000/taskmanagement/2
输出:
让我们尝试检索不在数据库中的元素。
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动词满足执行任务创建代码的条件。
输出:
让我们使用 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/
输出:
这里创建新任务所需的数据在-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
输出:
等效的 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 删除请求
HTTP DELETE 请求用于从数据库中删除特定任务。让我们看看 HTTPie 实用程序命令。
http DELETE :8000/taskmanagement/4
输出:
等效的 curl 命令如下:
curl -iX DELETE localhost:8000/taskmanagement/4
使用 Postman 发出 HTTP 请求
到目前为止,我们利用命令行工具来编写和发送 HTTP 请求。现在,我们将使用 Postman。 Postman REST 客户端是一个图形用户界面 (GUI) 工具,它有助于编写 HTTP 请求并将其发送到 Django 开发服务器。让我们编写和发送 GET 和 POST 请求。
获取请求
您可以在下拉菜单中选择 GET,在 URL 字段中输入 URL ( localhost:8000/taskmanagement/ ),然后点击发送按钮。邮递员将在输出正文部分中显示信息。下面的屏幕截图显示了 JSON 输出响应。
您可以单击页眉选项卡查看页眉详细信息。下面分享截图:
POST 请求
现在让我们使用 Postman GUI 工具发送 POST 请求。请按照以下步骤操作:
- 从下拉菜单中选择 POST 动词,
- 在 URL 字段中输入 URL ( localhost:8000/taskmanagement/ )
- 选择正文部分(在输入部分中)
- 检查原始单选按钮,并在 GraphQL 按钮右侧的下拉菜单中选择 JSON
- 输入以下几行 {“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:00.000000+00:00″, “status”:”Completed”, “payment_done”: “true”} 正文(输入部分) .并点击发送。
下面分享截图。
概括
在本文中,我们为 HTTP 请求创建了一个 Django API 视图,以便通过 RESTFul Web 服务与 SQLite 数据库进行交互。我们使用了 GET、POST、PUT 和 DELETE HTTP 动词。我们已经了解了如何使用命令行工具(curl 和 HTTPie)和 GUI 工具(POSTMAN)发送和编写 HTTP 请求。