Django 订单服务开发全流程指南
在开发订单服务时,我们需要创建视图、设置 URL 以及实现身份验证等功能。下面将详细介绍整个开发过程。
1. 创建辅助类和函数
在创建视图之前,我们先创建一些辅助类和函数,让视图代码更简洁。在主应用目录下创建
view_helper.py
文件,并添加以下导入语句:
from rest_framework import generics, status
from rest_framework.response import Response
from django.http import HttpResponse
from .exceptions import InvalidArgumentError
from .exceptions import OrderAlreadyCancelledError
from .exceptions import OrderAlreadyCompletedError
from .serializers import OrderSerializer
这些导入语句包含了 Django REST Framework 的通用视图类、HTTP 状态码、响应类,以及自定义异常和序列化器。
接下来,创建
OrderListAPIBaseView
类,作为返回订单列表视图的基类:
class OrderListAPIBaseView(generics.ListAPIView):
serializer_class = OrderSerializer
lookup_field = ''
def get_queryset(self, lookup_field_id):
pass
def list(self, request, *args, **kwargs):
try:
result = self.get_queryset(kwargs.get(self.lookup_field, None))
except Exception as err:
return Response(err, status=status.HTTP_400_BAD_REQUEST)
serializer = OrderSerializer(result, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
该类继承自
generics.ListAPIView
,提供了
get
和
list
方法。我们在子类中只需实现
get_queryset
方法即可。
然后,添加
set_status_handler
函数,用于处理 POST 请求:
def set_status_handler(set_status_delegate):
try:
set_status_delegate()
except (
InvalidArgumentError,
OrderAlreadyCancelledError,
OrderAlreadyCompletedError) as err:
return HttpResponse(err, status=status.HTTP_400_BAD_REQUEST)
return HttpResponse(status=status.HTTP_204_NO_CONTENT)
这个函数接收一个函数作为参数,执行该函数,如果出现异常则返回 400 响应,否则返回 204 响应。
2. 添加视图
在主应用目录下打开
views.py
文件,添加导入语句:
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from rest_framework import generics, status
from rest_framework.response import Response
from .models import Order
from .status import Status
from .view_helper import OrderListAPIBaseView
from .view_helper import set_status_handler
from .serializers import OrderSerializer
接下来,创建各种视图:
-
获取指定客户的所有订单
:
class OrdersByCustomerView(OrderListAPIBaseView):
lookup_field = 'customer_id'
def get_queryset(self, customer_id):
return Order.objects.get_all_orders_by_customer(customer_id)
- 获取指定客户的未完成订单 :
class IncompleteOrdersByCustomerView(OrderListAPIBaseView):
lookup_field = 'customer_id'
def get_queryset(self, customer_id):
return Order.objects.get_customer_incomplete_orders(customer_id)
- 获取指定客户的已完成订单 :
class CompletedOrdersByCustomerView(OrderListAPIBaseView):
lookup_field = 'customer_id'
def get_queryset(self, customer_id):
return Order.objects.get_customer_completed_orders(customer_id)
- 获取指定状态的订单列表 :
class OrderByStatusView(OrderListAPIBaseView):
lookup_field = 'status_id'
def get_queryset(self, status_id):
return Order.objects.get_orders_by_status(Status(status_id))
以上视图都只接受 GET 请求,返回订单列表。下面创建支持 POST 请求的视图,用于接收新订单:
class CreateOrderView(generics.CreateAPIView):
def post(self, request, *arg, **args):
serializer = OrderSerializer(data=request.data)
if serializer.is_valid():
order = serializer.save()
return Response(
{'order_id': order.id},
status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
最后,创建三个处理订单操作的函数:
def cancel_order(request, order_id):
order = get_object_or_404(Order, order_id=order_id)
return set_status_handler(
lambda: Order.objects.cancel_order(order)
)
def set_next_status(request, order_id):
order = get_object_or_404(Order, order_id=order_id)
return set_status_handler(
lambda: Order.objects.set_next_status(order)
)
def set_status(request, order_id, status_id):
order = get_object_or_404(Order, order_id=order_id)
try:
status = Status(status_id)
except ValueError:
return HttpResponse(
'The status value is invalid.',
status=status.HTTP_400_BAD_REQUEST)
return set_status_handler(
lambda: Order.objects.set_status(order, status)
)
3. 设置服务 URL
在主应用目录下打开
urls.py
文件,导入所需的视图类和函数:
from .views import (
cancel_order,
set_next_status,
set_status,
OrdersByCustomerView,
IncompleteOrdersByCustomerView,
CompletedOrdersByCustomerView,
OrderByStatusView,
CreateOrderView,
)
然后,添加 URL 配置:
from django.urls import path
urlpatterns = [
path(
r'order/add/',
CreateOrderView.as_view()
),
path(
r'customer/<int:customer_id>/orders/get/',
OrdersByCustomerView.as_view()
),
path(
r'customer/<int:customer_id>/orders/incomplete/get/',
IncompleteOrdersByCustomerView.as_view()
),
path(
r'customer/<int:customer_id>/orders/complete/get/',
CompletedOrdersByCustomerView.as_view()
),
path(
r'order/<int:order_id>/cancel',
cancel_order
),
path(
r'order/status/<int:status_id>/get/',
OrderByStatusView.as_view()
),
path(
r'order/<int:order_id>/status/<int:status_id>/set/',
set_status
),
path(
r'order/<int:order_id>/status/next/',
set_next_status
),
]
在
order
目录下的
urls.py
文件中,将主应用的 URL 配置包含进来,并设置前缀为
/api/
:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('main.urls')),
]
同时,别忘了导入
include
函数。
4. 启用身份验证
为了增加服务的安全性,我们启用令牌身份验证。在
order
目录下的
settings.py
文件中添加以下内容:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
在
INSTALLED_APPS
中添加
rest_framework.authtoken
:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'main',
'rest_framework',
'rest_framework.authtoken',
]
保存文件后,在终端运行以下命令进行数据库迁移:
python manage.py migrate
5. 创建测试脚本
创建
send_order.py
文件,用于测试 API:
import json
import sys
import argparse
from http import HTTPStatus
import requests
def setUpData(order_id):
data = {
"items": [
{
"name": "Prod 001",
"price_per_unit": 10,
"product_id": 1,
"quantity": 2
},
{
"name": "Prod 002",
"price_per_unit": 12,
"product_id": 2,
"quantity": 2
}
],
"order_customer": {
"customer_id": 14,
"email": "test@test.com",
"name": "Test User"
},
"order_id": order_id,
"status": 1,
"total": "190.00"
}
return data
def send_order(data):
response = requests.put(
'http://127.0.0.1:8000/api/order/add/',
data=json.dumps(data))
if response.status_code == HTTPStatus.NO_CONTENT:
print('Ops! Something went wrong!')
sys.exit(1)
print('Request was successfull')
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Create a order for test')
parser.add_argument('--orderid',
dest='order_id',
required=True,
help='Specify the the order id')
args = parser.parse_args()
data = setUpData(args.order_id)
send_order(data)
启动开发服务器:
python manage.py runserver
在另一个终端窗口运行测试脚本:
python send_order.py --orderid 10
运行脚本时可能会遇到 401 错误,表示未授权。我们需要在 Django 管理界面为用户创建令牌,并在请求头中添加令牌信息。修改
send_order
函数如下:
def send_order(data):
token = '744cf4f8bd628e62f248444a478ce06681cb8089'
headers = {
'Authorization': f'Token {token}',
'Content-type': 'application/json'
}
response = requests.put(
'http://127.0.0.1:8000/api/order/add/',
headers=headers,
data=json.dumps(data))
if response.status_code == HTTPStatus.NO_CONTENT:
print('Ops! Something went wrong!')
sys.exit(1)
print('Request was successfull')
再次运行脚本,应该能看到请求成功的提示。
6. 测试其他端点
我们可以使用
httpie
工具测试其他端点。安装
httpie
:
pip install httpie --upgrade --user
添加
httpie
到系统路径后,测试第一个 GET 端点:
http http://127.0.0.1:8000/api/customer/1/orders/get/ 'Authorization: Token 744cf4f8bd62...'
如果一切正常,你将看到预期的订单信息。
整个开发过程的流程图如下:
graph TD;
A[创建辅助类和函数] --> B[添加视图];
B --> C[设置服务URL];
C --> D[启用身份验证];
D --> E[创建测试脚本];
E --> F[测试其他端点];
通过以上步骤,我们完成了订单服务的开发、配置和测试。你可以继续尝试其他端点,确保服务正常运行。
Django 订单服务开发全流程指南
7. 详细操作步骤总结
为了更清晰地展示整个开发过程,我们将关键步骤总结如下:
1.
创建辅助类和函数
:
- 在主应用目录下创建
view_helper.py
文件。
- 导入所需模块和类。
- 创建
OrderListAPIBaseView
类作为基类。
- 实现
set_status_handler
函数处理 POST 请求。
2.
添加视图
:
- 在主应用目录下打开
views.py
文件。
- 导入所需模块和类。
- 创建各种视图类和处理函数。
3.
设置服务 URL
:
- 在主应用目录下打开
urls.py
文件。
- 导入视图类和函数。
- 配置 URL 规则。
- 在
order
目录下的
urls.py
文件中包含主应用 URL 并设置前缀。
4.
启用身份验证
:
- 在
order
目录下的
settings.py
文件中添加身份验证配置。
- 在
INSTALLED_APPS
中添加
rest_framework.authtoken
。
- 运行数据库迁移命令。
5.
创建测试脚本
:
- 创建
send_order.py
文件。
- 编写测试数据和发送请求的代码。
- 处理可能的错误和身份验证问题。
6.
测试其他端点
:
- 安装
httpie
工具。
- 使用
httpie
测试不同的 API 端点。
8. 常见问题及解决方法
在开发和测试过程中,可能会遇到一些常见问题,以下是一些解决方法:
| 问题描述 | 可能原因 | 解决方法 |
| — | — | — |
| 401 错误(未授权) | 未提供有效的身份验证令牌 | 在 Django 管理界面创建令牌,并在请求头中添加令牌信息 |
| 400 错误(错误请求) | 请求数据格式不正确或参数无效 | 检查请求数据和参数,确保符合 API 要求 |
| 404 错误(未找到) | URL 配置错误或资源不存在 | 检查 URL 配置,确保资源存在 |
9. 深入分析视图和 URL 配置
视图和 URL 配置是 Django 应用的核心部分,下面我们深入分析一下:
-
视图
:
-
继承关系
:不同的视图类继承自 Django REST Framework 的通用视图类,如
ListAPIView
和
CreateAPIView
,通过继承可以复用通用的功能。
-
方法重写
:在视图类中重写
get_queryset
和
post
等方法,实现自定义的业务逻辑。
-
序列化和反序列化
:使用
OrderSerializer
对数据进行序列化和反序列化,确保数据的正确传输和处理。
-
URL 配置
:
-
路径参数
:使用
<type:param>
格式的路径参数,方便传递动态数据。
-
视图映射
:将 URL 路径映射到相应的视图类或函数,实现请求的分发。
10. 代码优化建议
为了提高代码的可读性和可维护性,我们可以考虑以下优化建议:
-
代码注释
:在关键代码处添加详细的注释,解释代码的功能和实现思路。
-
异常处理
:在视图和函数中添加更详细的异常处理,提高系统的健壮性。
-
代码复用
:提取公共的代码逻辑,封装成函数或类,避免代码重复。
11. 总结与展望
通过以上步骤,我们成功开发了一个完整的订单服务,包括视图、URL 配置、身份验证和测试。在实际应用中,我们可以根据需求进一步扩展和优化这个服务,例如添加更多的 API 端点、优化数据库查询等。
同时,我们也可以将这个服务集成到更大的系统中,为用户提供更丰富的功能。希望这篇文章能帮助你更好地理解 Django 订单服务的开发过程,祝你在开发中取得成功!
整个开发过程的详细步骤流程图如下:
graph LR;
A[开始] --> B[创建 view_helper.py];
B --> C[导入模块和类];
C --> D[创建 OrderListAPIBaseView 类];
D --> E[实现 set_status_handler 函数];
E --> F[打开 views.py 文件];
F --> G[导入模块和类];
G --> H[创建各种视图类和函数];
H --> I[打开主应用 urls.py 文件];
I --> J[导入视图类和函数];
J --> K[配置 URL 规则];
K --> L[打开 order 目录 urls.py 文件];
L --> M[包含主应用 URL 并设置前缀];
M --> N[打开 settings.py 文件];
N --> O[添加身份验证配置];
O --> P[添加 rest_framework.authtoken 到 INSTALLED_APPS];
P --> Q[运行数据库迁移命令];
Q --> R[创建 send_order.py 文件];
R --> S[编写测试代码];
S --> T[处理身份验证问题];
T --> U[安装 httpie 工具];
U --> V[测试其他 API 端点];
V --> W[结束];
通过这个详细的流程图,我们可以更清晰地看到每个步骤之间的依赖关系和执行顺序。希望这个总结能帮助你更好地掌握整个开发过程。
Django订单服务开发全流程指南
超级会员免费看
27

被折叠的 条评论
为什么被折叠?



