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

Django模型@property属性值无法返回问题求助(DRF+Admin场景)

问题原因

你在模型里同时定义了total_inflasi数据库字段和同名的@property计算属性,Django会优先读取数据库字段的值(这里是null),导致你的计算属性根本没被调用,自然在Admin和API里显示不出来。

修复方案

有两种可行的解决思路,根据你的需求选择:


方案1:保留数据库字段,重命名计算属性

如果需要保留数据库里的total_inflasi字段(比如要保留历史数据),把计算属性改名避免冲突:

修改models.py

把@property的名称改成calculated_total_inflasi,同时处理字段为null的情况防止求和报错:

class Inflasi(models.Model):
    sandang = models.FloatField(null=True)
    sembako = models.FloatField(null=True)
    perumahan = models.FloatField(null=True)
    kesehatan = models.FloatField(null=True)
    transportasi = models.FloatField(null=True)
    informasi = models.FloatField(null=True)
    rekreasi = models.FloatField(null=True)
    pendidikan = models.FloatField(null=True)
    penyedia_pangan = models.FloatField(null=True)
    perawatan_pribadi = models.FloatField(null=True)
    total_inflasi = models.FloatField(null=True)  # 保留数据库字段
    tanggal = models.DateField(null=True)

    @property
    def calculated_total_inflasi(self):
        fields = [
            self.sandang, self.sembako, self.perumahan, self.kesehatan,
            self.transportasi, self.informasi, self.rekreasi, self.pendidikan,
            self.penyedia_pangan, self.perawatan_pribadi
        ]
        # 过滤null值后求和,避免报错
        return sum(f for f in fields if f is not None)

    def __str__(self):
        return str(self.tanggal)

    class Meta:
        verbose_name = "Inflasi"
        verbose_name_plural = "Inflasi"

修改admin.py

在Admin配置中显式添加计算属性到显示字段:

@admin.register(Inflasi)
class InflasiModelAdmin(ImportExportModelAdmin):
    list_display = [
        'tanggal', 'sandang', 'sembako', 'perumahan', 'kesehatan',
        'transportasi', 'informasi', 'rekreasi', 'pendidikan',
        'penyedia_pangan', 'perawatan_pribadi', 'total_inflasi', 'calculated_total_inflasi'
    ]
    fields = list_display  # 详情页显示相同字段

修改DRF序列化器

在序列化器中添加计算属性作为只读字段:

from rest_framework import serializers
from .models import Inflasi

class InflasiSerializer(serializers.ModelSerializer):
    calculated_total_inflasi = serializers.ReadOnlyField()

    class Meta:
        model = Inflasi
        fields = '__all__'

方案2:移除数据库字段,保留计算属性

如果不需要把total_inflasi存储到数据库,直接用计算属性:

修改models.py

删除total_inflasi数据库字段,保留@property并处理null值:

class Inflasi(models.Model):
    sandang = models.FloatField(null=True)
    sembako = models.FloatField(null=True)
    perumahan = models.FloatField(null=True)
    kesehatan = models.FloatField(null=True)
    transportasi = models.FloatField(null=True)
    informasi = models.FloatField(null=True)
    rekreasi = models.FloatField(null=True)
    pendidikan = models.FloatField(null=True)
    penyedia_pangan = models.FloatField(null=True)
    perawatan_pribadi = models.FloatField(null=True)
    tanggal = models.DateField(null=True)  # 移除数据库字段total_inflasi

    @property
    def total_inflasi(self):
        fields = [
            self.sandang, self.sembako, self.perumahan, self.kesehatan,
            self.transportasi, self.informasi, self.rekreasi, self.pendidikan,
            self.penyedia_pangan, self.perawatan_pribadi
        ]
        return sum(f for f in fields if f is not None)

    def __str__(self):
        return str(self.tanggal)

    class Meta:
        verbose_name = "Inflasi"
        verbose_name_plural = "Inflasi"

执行数据库迁移命令,移除数据库中的对应字段:

python manage.py makemigrations
python manage.py migrate

修改admin.py

在Admin中添加计算属性,并设置为只读:

@admin.register(Inflasi)
class InflasiModelAdmin(ImportExportModelAdmin):
    list_display = [
        'tanggal', 'sandang', 'sembako', 'perumahan', 'kesehatan',
        'transportasi', 'informasi', 'rekreasi', 'pendidikan',
        'penyedia_pangan', 'perawatan_pribadi', 'total_inflasi'
    ]
    fields = list_display
    readonly_fields = ['total_inflasi']  # 计算属性不可编辑

修改DRF序列化器

在序列化器中添加total_inflasi作为只读字段:

from rest_framework import serializers
from .models import Inflasi

class InflasiSerializer(serializers.ModelSerializer):
    total_inflasi = serializers.ReadOnlyField()

    class Meta:
        model = Inflasi
        fields = '__all__'

内容的提问来源于stack exchange,提问作者Amarulloh M Khoeri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 19:15:33