当前位置: 首页 > news >正文

用Django REST Framework从零搭建共享充电桩后台API(附完整项目结构)

从零构建共享充电桩API:Django REST Framework工程化实践

共享充电桩作为城市基础设施的重要组成部分,其后台系统的稳定性和扩展性直接影响用户体验。本文将带你从零开始,用Django REST Framework构建一个符合生产标准的API系统。不同于简单的功能堆砌,我们更关注项目脚手架设计代码组织规范API设计原则,这些才是支撑长期迭代的关键。

1. 环境配置与项目初始化

在开始编码前,合理的开发环境配置能避免后续大量"坑点"。推荐使用Python 3.8+和Django 3.2+的组合,这是目前企业级项目最稳定的版本搭配。

# 创建虚拟环境(推荐使用venv) python -m venv venv source venv/bin/activate # Linux/Mac venv\Scripts\activate # Windows # 安装核心依赖 pip install django==3.2.16 djangorestframework==3.14.0

项目结构设计应该遵循模块化关注点分离原则。以下是经过多个物联网项目验证的标准结构:

shared_charging/ ├── config/ # 项目配置目录(原settings.py位置) │ ├── __init__.py │ ├── settings.py # 拆分为多个配置文件 │ ├── urls.py │ └── asgi.py ├── apps/ # 所有应用模块 │ ├── chargers/ # 充电桩模块 │ ├── users/ # 用户模块 │ └── ... # 其他模块 ├── scripts/ # 部署和管理脚本 ├── requirements/ # 分环境依赖文件 │ ├── base.txt # 基础依赖 │ └── local.txt # 开发环境特有依赖 └── manage.py

提示:使用python manage.py startapp创建应用时,建议通过--template参数加载自定义模板,确保所有应用初始结构一致。

2. 数据模型设计实战

充电桩系统的核心在于数据模型的设计。我们需要考虑设备状态管理订单生命周期计费策略等多个业务维度。

2.1 充电桩模型设计

# apps/chargers/models.py from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator class Charger(models.Model): class Status(models.TextChoices): ONLINE = 'online', '在线' OFFLINE = 'offline', '离线' MAINTENANCE = 'maintenance', '维护中' charger_id = models.CharField(max_length=32, unique=True) location = models.CharField(max_length=200) power_output = models.PositiveIntegerField( # 输出功率(W) validators=[MinValueValidator(1000), MaxValueValidator(22000)] ) status = models.CharField( max_length=12, choices=Status.choices, default=Status.ONLINE ) last_heartbeat = models.DateTimeField(null=True) def __str__(self): return f"{self.charger_id}@{self.location}"

2.2 订单模型设计

订单系统需要处理状态流转计费逻辑

# apps/orders/models.py from django.db import models from django.core.validators import MinValueValidator class Order(models.Model): class Status(models.TextChoices): CREATED = 'created', '已创建' CHARGING = 'charging', '充电中' COMPLETED = 'completed', '已完成' CANCELLED = 'cancelled', '已取消' user = models.ForeignKey('users.User', on_delete=models.PROTECT) charger = models.ForeignKey('chargers.Charger', on_delete=models.PROTECT) start_time = models.DateTimeField(auto_now_add=True) end_time = models.DateTimeField(null=True) consumed_kwh = models.DecimalField( max_digits=6, decimal_places=2, validators=[MinValueValidator(0.01)], null=True ) status = models.CharField( max_length=10, choices=Status.choices, default=Status.CREATED ) @property def duration(self): if self.end_time: return self.end_time - self.start_time return None

注意:金额计算建议使用DecimalField而非FloatField,避免浮点数精度问题。

3. API端点设计与实现

RESTful API设计应该遵循资源导向原则,同时考虑物联网设备的特殊性。

3.1 充电桩API实现

使用DRF的ViewSet可以快速构建CRUD接口,但需要添加设备状态管理等业务逻辑:

# apps/chargers/api/views.py from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from ..models import Charger from .serializers import ChargerSerializer class ChargerViewSet(viewsets.ModelViewSet): queryset = Charger.objects.all() serializer_class = ChargerSerializer @action(detail=True, methods=['post']) def heartbeat(self, request, pk=None): charger = self.get_object() charger.last_heartbeat = timezone.now() charger.save() return Response({'status': 'updated'}) @action(detail=True, methods=['post']) def start_charging(self, request, pk=None): # 实现启动充电的业务逻辑 ...

3.2 订单API的特殊处理

订单创建需要处理业务验证状态机转换

# apps/orders/api/views.py from rest_framework import viewsets from rest_framework.exceptions import ValidationError from ..models import Order class OrderViewSet(viewsets.ModelViewSet): queryset = Order.objects.all() serializer_class = OrderSerializer def perform_create(self, serializer): charger = serializer.validated_data['charger'] if charger.status != Charger.Status.ONLINE: raise ValidationError('充电桩不可用') # 检查用户是否有未完成订单 if Order.objects.filter( user=serializer.validated_data['user'], status__in=[Order.Status.CREATED, Order.Status.CHARGING] ).exists(): raise ValidationError('存在进行中的订单') serializer.save(status=Order.Status.CREATED)

4. 项目进阶配置

4.1 分页与过滤配置

config/settings.py中添加DRF全局配置:

REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 20, 'DEFAULT_FILTER_BACKENDS': [ 'django_filters.rest_framework.DjangoFilterBackend', 'rest_framework.filters.OrderingFilter' ], }

4.2 API文档生成

使用drf-yasg或drf-spectacular自动生成API文档:

pip install drf-spectacular

配置settings.py:

INSTALLED_APPS += ['drf_spectacular'] REST_FRAMEWORK = { # ...其他配置 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', } SPECTACULAR_SETTINGS = { 'TITLE': '共享充电桩API文档', 'VERSION': '1.0.0', 'SERVE_INCLUDE_SCHEMA': False, }

在根urls.py中添加:

from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView urlpatterns = [ # ...其他路由 path('api/schema/', SpectacularAPIView.as_view(), name='schema'), path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='docs'), ]

5. 测试与部署准备

5.1 编写API测试用例

使用DRF的APITestCase编写集成测试:

# apps/chargers/tests/test_api.py from rest_framework.test import APITestCase from django.urls import reverse from ..models import Charger class ChargerAPITests(APITestCase): @classmethod def setUpTestData(cls): cls.charger = Charger.objects.create( charger_id="TEST001", location="测试位置", power_output=7500 ) def test_get_charger_list(self): url = reverse('charger-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data['results']), 1)

5.2 生产环境配置建议

创建config/settings/production.py

from .base import * DEBUG = False DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.getenv('DB_NAME'), 'USER': os.getenv('DB_USER'), 'PASSWORD': os.getenv('DB_PASSWORD'), 'HOST': os.getenv('DB_HOST'), 'PORT': os.getenv('DB_PORT', '5432'), } } # 安全配置 SECURE_HSTS_SECONDS = 3600 SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True

在项目实践中,我们发现合理的错误处理能大幅降低运维成本。建议为所有API添加统一的异常处理中间件:

# config/middleware/exception_handler.py import logging from rest_framework.response import Response from rest_framework import status logger = logging.getLogger(__name__) class APIExceptionHandler: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): return self.get_response(request) def process_exception(self, request, exception): logger.error(f"API异常: {str(exception)}", exc_info=True) return Response( {'error': '服务器内部错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR )
http://www.jsqmd.com/news/563976/

相关文章:

  • 2026年岩棉板市场口碑佳选,实力厂家口碑推荐一览,复合岩棉板/电伴热带/憎水岩棉板/橡塑保温管,岩棉板厂家口碑推荐 - 品牌推荐师
  • 从LED灯变化理解计算机移位运算:手把手教你用实验箱验证带进位左移
  • 华为欧拉系统(openEuler 22.03 LTS)上,用Docker Compose V2部署你的第一个微服务项目
  • Bidili Generator免配置:自动检测GPU/选择精度/加载LoRA的智能初始化流程
  • cv_resnet101_face-detection_cvpr22papermogface 模型部署的网络安全考量:防范403 Forbidden等常见攻击
  • 终极PS4游戏修改神器:GoldHEN Cheats Manager完全指南
  • SDMatte赋能微信小程序:在线证件照制作与背景替换应用开发
  • 给物联网设备选‘安全锁’:PRESENT、SPECK、SIMON三大轻量级密码算法实战选型指南
  • 永磁同步电机这玩意儿现在工业上用得是真多,今天咱们来点硬核的,手搓个IPMSM的数学模型。先别急着关页面,代码实现和调试坑点都给你备好了
  • 2026年靠谱的cnc数控机床/五轴数控机床/六轴数控机床/五轴联动数控机床制造厂家推荐 - 行业平台推荐
  • 保姆级教程:在本地环境复现谷歌Code as Policies项目(含避坑指南)
  • Java应用Istio mTLS启用后gRPC调用持续超时?紧急解锁x509证书链校验、SNI配置与Java SSLContext动态刷新机制
  • Vision Master OpenCV 2.0 深度评测:新增YOLOv5、语义分割等ONNX模型,实战性能提升有多大?
  • TikTok直播限流怎么办?2026 最新原因分析与恢复流量实操方案
  • Xcode12空间优化技巧:删除这些不常用的模拟器运行时文件,瞬间多出12G
  • Hi3559平台ISP调试实战:从参数配置到画质优化
  • 分布式系统设计:一致性与可用性的权衡
  • StarRocks数据库连接指南:解决Python中使用starrocks库的常见问题
  • 2026年知名的围挡护栏/球场护栏/体育场护栏精选厂家 - 行业平台推荐
  • Z-Image-Turbo-rinaiqiao-huiyewunv 学术研究辅助:快速生成论文图表与示意图
  • RAG知识库实战指南:从架构设计到审计法规检索案例
  • 自动驾驶域接口技术解析:从硬件架构到车内通信
  • 2026招投标装企管理软件应用白皮书:装修公司erp管理软件、装修公司管理系统、装修公司财务管理系统、装修公司财务管理软件选择指南 - 优质品牌商家
  • 从零搭建:在VS Code中集成Cppcheck与MISRA-C的实时代码卫士
  • Token经济学全景报告
  • 基于STM32的智能药箱系统开发实战:从硬件搭建到云端互联
  • 163MusicLyrics:3秒获取双平台歌词的开源工具革新方案
  • 163MusicLyrics:跨平台歌词提取工具全解析
  • Ubuntu 20.04离线装MySQL 8.0.20,我踩过的那些依赖包的坑(附libaio1、libmecab2下载链接)
  • 告别Navicat!免费神器DBeaver保姆级配置教程(含中文设置与驱动加速)