You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 05:16:34