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

Django中非数据库模型Portfolio重复添加Position问题咨询

问题描述

我尝试在Django中定义非数据库模型Position与Portfolio,相关实现代码如下:

# models.py
class Position(models.Model):
    code = None
    price = None
    value = None

    class Meta:
        managed = False

    def __init__(self, code, price, value):
        self.code = code
        self.price = price
        self.value = value

class Portfolio(models.Model):
    positions = []

    class Meta:
        managed = False

    def add(self, position):
        self.positions.append(position)


class PositionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Position
        fields = ['code', 'price', 'value']

# serializers.py
class PortfolioSerializer(serializers.ModelSerializer):
    positions = PositionSerializer(many=True)

    class Meta:
        model = Portfolio
        fields = ['positions']


# views.py
class PortfolioDetail(APIView):
    """
    List all portfolios, or create a new portfolio.
    """
    def get(self, request, analyzer_id, date, format=None):
        logger.warning('requesting portfolio using {} on {}'.format(analyzer_id, date))
        portfolio = Portfolio()
        portfolio.add(Position('600519', 1900.0, 50000))
        serializer = PortfolioSerializer(portfolio)
        return Response(serializer.data)

当前遇到的问题是:每次刷新页面时,Portfolio中的Position都会被重复添加,多次刷新后会出现多个Position,请问这是什么原因?

问题原因及解决方法

原因分析

问题出在Portfolio类的positions属性定义上——你把它定义成了类属性,而非实例属性。在Python中,类属性是所有类实例共享的,不会在每次创建新实例时重新初始化。

第一次创建Portfolio实例时,positions列表被初始化并添加了一个Position;后续每次创建新实例时,这个类属性的列表已经保留了之前的元素,新的Position会继续追加进去,导致每次请求都会累积之前的数据,出现重复添加的情况。

解决方法

方法一:修改模型类,将类属性改为实例属性

把positions移到__init__方法中初始化,确保每个Portfolio实例都有独立的列表:

class Portfolio(models.Model):
    class Meta:
        managed = False

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  # 必须调用父类__init__,避免Django模型初始化异常
        self.positions = []  # 实例属性,每个实例独立拥有

    def add(self, position):
        self.positions.append(position)

方法二:改用普通Python类(推荐)

既然是非数据库模型,没必要继承models.Model,用普通类更简洁,避免引入Django模型的冗余逻辑:

# models.py 改用普通类
class Position:
    def __init__(self, code, price, value):
        self.code = code
        self.price = price
        self.value = value

class Portfolio:
    def __init__(self):
        self.positions = []

    def add(self, position):
        self.positions.append(position)

对应的序列化器也要调整为Serializer(而非ModelSerializer):

# serializers.py
class PositionSerializer(serializers.Serializer):
    code = serializers.CharField()
    price = serializers.FloatField()
    value = serializers.FloatField()

class PortfolioSerializer(serializers.Serializer):
    positions = PositionSerializer(many=True)

这种写法更贴合非数据库模型的使用场景,减少不必要的复杂度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:04:56