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

Django Rest Framework嵌套序列化器返回空列表问题求助

问题分析与修复方案

核心问题

访问/assessments返回空列表的根本原因是:提交Return数据时没有生成对应的Assessment记录,同时代码中存在关键字冲突、属性调用错误、序列化器字段不匹配等问题。


分步修复

1. 模型层修复(解决关键字冲突与属性错误)

return是Python关键字,不能作为模型字段名;同时修正Assessment中错误的属性调用逻辑:

from django.db import models
import calendar
from calendar import monthrange

class Return(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)
    actual_turnover = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateField(auto_now=True)
    
    class Meta:
        verbose_name = 'Return'
        verbose_name_plural = 'Returns'

    def __str__(self):
        return f'{self.room_type}'
    
    def days_in_month(self):
        year = self.created_at.year
        month = self.created_at.month
        num_days = monthrange(year, month)[1]
        return num_days

    @property
    def potential_turnover(self) -> float:
        return float(self.days_in_month()) * float(self.number_of_rooms) * float(self.price_per_night)
    
    @property
    def total_number_of_rooms(self) -> float:
        # 用ORM聚合替代循环,性能更优
        return Return.objects.aggregate(total=models.Sum('number_of_rooms'))['total'] or 0
    
    @property
    def total_potential_turnover(self) -> float:
        total = 0
        for obj in Return.objects.all():
            total += obj.potential_turnover
        return total
  
    @property
    def gross_amount(self) -> float:
        # 用ORM聚合替代循环,性能更优
        return Return.objects.aggregate(total=models.Sum('actual_turnover'))['total'] or 0

class Assessment(models.Model):
    # 替换关键字字段名,避免语法冲突
    return_instance = models.ForeignKey(Return, related_name="assessments", on_delete=models.CASCADE)
    created_at = models.DateField(auto_now=True)

    class Meta:
        verbose_name = 'Assessment'
        verbose_name_plural = 'Assessments'

    def __str__(self):
        return f'{self.return_instance.room_type}'
    
    @property
    def gross_amount(self) -> float:
        # ForeignKey是单个对象,直接关联对应Return的actual_turnover
        return float(self.return_instance.actual_turnover)
    
    @property
    def total_levy_charges(self) -> float:
        adjustment = 0
        # property不需要加括号调用
        return self.gross_amount - adjustment
    
    @property
    def bed_night_levy_payable(self) -> float:
        rate_of_bed_night_levy = 0.01
        return rate_of_bed_night_levy * self.total_levy_charges
    
    @property
    def total_monthly_bed_night_levy(self) -> float:
        penalty = 0
        return penalty + self.bed_night_levy_payable

2. 序列化器修复(解决创建逻辑错误与字段匹配)

修正ReturnSerializer的create方法,确保创建Return时自动生成对应的Assessment;同时调整AssessmentSerializer的关联字段:

from rest_framework import serializers
from .models import Return, Assessment

class ReturnSerializer(serializers.ModelSerializer):
    class Meta:
        model = Return
        fields = (
            'id',
            'room_type',
            'number_of_rooms',
            'total_number_of_rooms',
            'price_per_night',
            'potential_turnover',
            'actual_turnover',
            'total_potential_turnover',
            'gross_amount'
        )
    
    def create(self, validated_data):
        # 创建Return实例
        return_instance = Return.objects.create(**validated_data)
        # 自动关联生成Assessment记录
        Assessment.objects.create(return_instance=return_instance)
        return return_instance

class AssessmentSerializer(serializers.ModelSerializer):
    # 关联修正后的模型字段,实现嵌套序列化
    return_instance = ReturnSerializer()
    
    class Meta:
        model = Assessment
        fields = [
            'id',
            'return_instance',
            'created_at',
            'gross_amount',
            'total_levy_charges',
            'bed_night_levy_payable',
            'total_monthly_bed_night_levy'
        ]

3. 视图与URL层(无需修改)

原视图和URL配置逻辑正常,保持不变即可。


修复效果

  1. 提交/returns数据时,会自动在Assessment表中生成关联记录;
  2. 访问/assessments时,会返回包含嵌套Return数据的完整列表,示例响应如下:
"results": [
    {
        "id": 1,
        "return_instance": {
            "id": 1,
            "room_type": "Single",
            "number_of_rooms": 2,
            "total_number_of_rooms": 2,
            "price_per_night": "10000.00",
            "potential_turnover": 40000.0,
            "actual_turnover": "8000.00",
            "total_potential_turnover": 40000.0,
            "gross_amount": 8000.0
        },
        "created_at": "2024-05-20",
        "gross_amount": 8000.0,
        "total_levy_charges": 8000.0,
        "bed_night_levy_payable": 80.0,
        "total_monthly_bed_night_levy": 80.0
    }
]

内容的提问来源于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.26 05:09:54