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
相关产品推荐
相关产品推荐

