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

Django DRF Serializer传递参数给模型带参属性方法报错如何解决

报错根本原因

你遇到的'int' object is not callable报错核心是@property装饰器的用法错误:被@property装饰的方法会被转换为只读属性,调用时不需要加括号,也不支持传入自定义参数。当你执行object.balance(sell_type)时,object.balance已经是方法返回的整数结果,自然无法作为函数调用。

修复方案

1. 修改模型层代码,移除@property装饰器

将models.py中的balance改为普通实例方法即可支持传参:

class Item(models.Model):
    entered_by = models.ForeignKey(User, on_delete=models.PROTECT)
    name = models.CharField(max_length=50, blank=True)

    # 移除@property装饰器
    def balance(self, stock_type='Retail'):
        stock = Stock.objects.filter(item=self, type=stock_type, status='InStock').aggregate(models.Sum('quantity')).get('quantity__sum')
        return stock or 0

2. 修改序列化层调用逻辑

现在balance是普通实例方法,无论是否传自定义参数都需要主动调用:

from rest_framework import serializers
from .models import Item

class ItemSerializer(serializers.ModelSerializer):
    balance = serializers.SerializerMethodField()

    class Meta:
        model = Item
        fields = ('entered_by', 'name', 'balance', 'sell_mode')
    
    def get_balance(self, object):
        sell_type = self.context.get("sell_type")
        if sell_type:
            return object.balance(sell_type)
        # 无自定义参数时调用方法使用默认参数,不要直接返回object.balance
        return object.balance()

可选兼容方案

如果你的其他业务代码中已经用到了item.balance的属性调用形式,可以额外保留属性定义:

class Item(models.Model):
    # ... 其他字段不变
    def balance(self, stock_type='Retail'):
        stock = Stock.objects.filter(item=self, type=stock_type, status='InStock').aggregate(models.Sum('quantity')).get('quantity__sum')
        return stock or 0
    
    # 额外定义只读属性兼容旧代码调用
    @property
    def balance_property(self):
        return self.balance()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 01:42:03