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

如何在Django REST Framework同应用中实现跨模型数据提交与读取

一对多关联模型的提交与只读计算数据实现

需求:通过/returns端点提交BedNightReturn数据,/assessments端点以只读方式获取包含计算字段的评估数据。

1. 模型定义

class BedNightReturn(models.Model):
    room_type = models.CharField(max_length=50)
    number_of_rooms = models.PositiveSmallIntegerField()
    price_per_night = models.DecimalField(max_digits=10, decimal_places=2)
    days_in_month = models.PositiveSmallIntegerField()
    
    class Meta:
        verbose_name = 'BedNightReturn'
        verbose_name_plural = 'BedNightReturns'

    def __str__(self):
        return f'{self.room_type}'

class BedNightReturnAssessment(models.Model):
    assessment = models.ForeignKey(BedNightReturn, related_name = "assessments", on_delete=models.CASCADE)
   

    class Meta:
        verbose_name = 'BedNightReturnAssessment'
        verbose_name_plural = 'BedNightReturnAssessments'

    def __str__(self):
        return f'{self.assessment.room_type}'
    
    @property
    def potential_turnover(self) -> float:
        days_in_month = 30
        return float(days_in_month) * float(self.assessment.number_of_rooms) * float(self.assessment.price_per_night)
    
    @property
    def actual_turnover(self) -> float:
        return float(self.assessment.days_in_month) * float(self.assessment.number_of_rooms) * float(self.assessment.price_per_night)

2. 序列化器定义

class BedNightReturnSerializer(ModelSerializer):
    class Meta:
        model = BedNightReturn
        fields = (
            'id',
            'room_type',
            'number_of_rooms',
            'price_per_night',
            'days_in_month',
            
        )

class BedNightReturnAssessmentSerializer(ModelSerializer):
    assessment = BedNightReturnSerializer()
    potential_turnover = ReadOnlyField()
    actual_turnover = ReadOnlyField()
    class Meta:
        model = BedNightReturnAssessment
        fields = (
            'id',
            'assessment',
            'potential_turnover',
            'actual_turnover',
        )

3. 视图定义

调整评估视图为只读模式,确保/assessments端点仅支持查询操作:

from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet

class BedNightReturnViewSet(ModelViewSet):
    queryset = BedNightReturn.objects.all()
    serializer_class = BedNightReturnSerializer

class BedNightReturnAssessmentViewSet(ReadOnlyModelViewSet):
    queryset = BedNightReturnAssessment.objects.all()
    serializer_class = BedNightReturnAssessmentSerializer   

4. URL配置

from django.urls import include, path
from rest_framework import routers

from bednightlevy.views import (
    BedNightReturnAssessmentViewSet,
    BedNightReturnViewSet,
)

router = routers.DefaultRouter(trailing_slash = False)

router.register('returns', BedNightReturnViewSet, basename="bednight")
router.register('assessments', BedNightReturnAssessmentViewSet, basename='bednight_assessment')

urlpatterns = [
    path('',include(router.urls)),
]

补充优化说明

  • 自动生成评估记录:当前提交BedNightReturn后不会自动创建对应的评估记录,若需要自动关联,可在BedNightReturn的save方法中添加逻辑:
class BedNightReturn(models.Model):
    # 原有字段及方法...
    
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        # 仅在无关联评估记录时创建
        if not self.assessments.exists():
            BedNightReturnAssessment.objects.create(assessment=self)

内容的提问来源于stack exchange,提问作者Lodyne Mark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 13:05:43