基于Django Rest Framework的效率计算API:POST后计算实现问询
Django Rest Framework 效率计算API 实现方案
一、项目结构推荐
采用标准DRF项目结构,将核心业务拆分至独立app(如production),便于维护和扩展:
efficiency_api/ ├── efficiency_api/ # 项目配置根目录 │ ├── __init__.py │ ├── settings.py # 配置DRF、数据库等 │ ├── urls.py # 全局路由 │ └── wsgi.py ├── production/ # 业务app,处理生产数据与效率计算 │ ├── __init__.py │ ├── admin.py # 后台管理配置 │ ├── apps.py │ ├── models.py # 定义数据模型与计算逻辑 │ ├── serializers.py # API序列化逻辑 │ ├── signals.py # 信号处理(可选) │ ├── urls.py # app路由 │ └── views.py # API视图 └── manage.py
二、触发计算函数的常用方式
根据业务场景选择合适的触发时机,以下三种是最常用的方案:
1. 模型层重写save()方法(推荐,通用型)
直接在模型中处理计算逻辑,无论通过API、后台管理还是其他方式保存数据,都会自动触发计算,确保数据一致性。
2. 使用Django post_save信号(解耦型)
将计算逻辑与模型分离,适合复杂业务场景,便于后续扩展。
3. 序列化器层处理(API专属型)
仅在API请求触发保存时计算,适合只需要通过API操作数据的场景。
三、代码示例
1. 模型定义(production/models.py)
from django.db import models class ProductionData(models.Model): energy_consumption = models.FloatField(verbose_name="能耗") production_output = models.FloatField(verbose_name="产能") efficiency = models.FloatField(verbose_name="效率", blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def calculate_efficiency(self): # 效率计算公式:效率 = 产能 / 能耗(可根据实际需求调整) if self.energy_consumption == 0: return 0.0 return round(self.production_output / self.energy_consumption, 2) # 方式一:重写save方法触发计算 def save(self, *args, **kwargs): self.efficiency = self.calculate_efficiency() super().save(*args, **kwargs) def __str__(self): return f"Production Record {self.id} - Efficiency: {self.efficiency}"
2. 信号处理(可选,production/signals.py)
如果选择用信号替代模型save()方法,先注释模型中的save()重写,再添加以下代码:
from django.db.models.signals import post_save from django.dispatch import receiver from .models import ProductionData @receiver(post_save, sender=ProductionData) def update_efficiency_on_save(sender, instance, created, **kwargs): # 避免递归调用,先检查效率是否已计算 calculated_efficiency = instance.calculate_efficiency() if instance.efficiency != calculated_efficiency: instance.efficiency = calculated_efficiency # 使用update_fields避免再次触发post_save信号 instance.save(update_fields=['efficiency'])
然后在production/apps.py中注册信号:
from django.apps import AppConfig class ProductionConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'production' def ready(self): import production.signals
3. 序列化器(production/serializers.py)
如果选择在序列化器层处理计算,注释模型的save()和信号,修改序列化器:
from rest_framework import serializers from .models import ProductionData class ProductionDataSerializer(serializers.ModelSerializer): class Meta: model = ProductionData fields = ['id', 'energy_consumption', 'production_output', 'efficiency', 'created_at', 'updated_at'] read_only_fields = ['efficiency', 'created_at', 'updated_at'] def create(self, validated_data): instance = ProductionData.objects.create(**validated_data) instance.efficiency = instance.calculate_efficiency() instance.save() return instance def update(self, instance, validated_data): instance.energy_consumption = validated_data.get('energy_consumption', instance.energy_consumption) instance.production_output = validated_data.get('production_output', instance.production_output) instance.efficiency = instance.calculate_efficiency() instance.save() return instance
4. API视图(production/views.py)
使用ModelViewSet快速实现CRUD接口:
from rest_framework import viewsets from .models import ProductionData from .serializers import ProductionDataSerializer class ProductionDataViewSet(viewsets.ModelViewSet): queryset = ProductionData.objects.all() serializer_class = ProductionDataSerializer
5. 路由配置
- 项目根路由(
efficiency_api/urls.py):
from django.contrib import admin from django.urls import path, include from rest_framework.routers import DefaultRouter from production.views import ProductionDataViewSet router = DefaultRouter() router.register(r'production', ProductionDataViewSet) urlpatterns = [ path('admin/', admin.site.urls), path('api/', include(router.urls)), ]
四、测试验证
发送POST请求到http://localhost:8000/api/production/,示例请求体:
{ "energy_consumption": 100, "production_output": 85 }
返回结果中会自动包含计算后的efficiency字段(示例中为0.85)。
内容的提问来源于stack exchange,提问作者Doruk Karaca
相关产品推荐
相关产品推荐

