我有两个代表一对多关系的模型。 InterestRateCurve对象可以有许多InterestRate对象。 问题是,当我有一个函数创建两条曲线,其中每条曲线有一个速率时,第二条曲线的速率会覆盖第一条曲线的速率。所以,我最终在数据库中有两行曲线和一行速率。 当我执行一个保存一条曲线和一个速率的程序,然后执行一个单独的程序,以一个速率保存另一条曲线时,它就没事了。
我使用Python 2.7和Django 1.4。
模型:
class InterestRate(models.Model):
type = models.CharField(max_length=20)
term = modelFields.tgTimePeriodField(max_length=20)
numTerms = models.IntegerField()
mid = models.FloatField()
curve = models.ForeignKey('InterestRateCurve')
class Meta:
unique_together = ('type', 'term', 'numTerms', 'curve')
def __unicode__(self):
return "%s/%s/%s/%s" % (self.type, self.term, self.numTerms, self.curve)
def __str__(self):
return "%s/%s/%s/%s/%s" % (self.type, self.term, self.numTerms, self.mid, self.curve)
class InterestRateCurve(models.Model):
ccy = modelFields.tgCurrencyField(max_length=20)
index = models.CharField(max_length=20)
term = modelFields.tgTimePeriodField(max_length=20)
numTerms = models.IntegerField()
asOf = modelFields.tgDateField()
cvid = models.CharField(max_length=20, blank=True, default='')
#rates needs to be explicitly maintained inside class for convenience
rates = []
class Meta:
unique_together = ('ccy', 'index', 'term', 'numTerms', 'asOf', 'cvid')
def __unicode__(self):
return "%s/%s/%s/%s/%s/%s" % (self.ccy, self.index, self.term, \
self.numTerms, self.asOf, self.cvid)
def save(self):
try:
curve = InterestRateCurve.objects.get(ccy=self.ccy, index=self.index,\
term=self.term, numTerms=self.numTerms,\
asOf=self.asOf, cvid=self.cvid)
#Delete all rates before saving the new rates
oldRates = curve.interestrate_set.all()
for oldRate in oldRates:
oldRate.delete()
for rate in self.rates:
rate.curve = curve
rate.save()
except InterestRateCurve.DoesNotExist:
super(InterestRateCurve, self).save()
curve = InterestRateCurve.objects.get(ccy=self.ccy, index=self.index,\
term=self.term, numTerms=self.numTerms,\
asOf=self.asOf, cvid=self.cvid)
for rate in self.rates:
rate.curve = curve
rate.save()
def addRate(self, rate):
rate.curve = self
exists = False
for r in self.rates:
if r.type == rate.type:
if r.term == rate.term:
if r.numTerms == rate.numTerms:
exists = True
continue
if exists == False:
self.rates.append(rate)
以下代码可以正常使用:
date = tgDate(month=9,day=12,year=2011)
curve = InterestRateCurve(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=self.asOf, cvid='TESTSAVE2CURVES')
curve.save()
curve = InterestRateCurve.objects.get(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=date, cvid='TESTSAVE2CURVES')
rate = InterestRate(term='M', numTerms=1, type='Deposit', mid=0.01, curve=curve)
curve.addRate(rate)
curve.save()
此执行会导致保存一条曲线和一条速率。
在单独的执行中我运行:
date = tgDate(month=9,day=13,year=2011) #DATE DIFFERS
curve = InterestRateCurve(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=date, cvid='TESTSAVE2CURVES')
curve.save()
curve = InterestRateCurve.objects.get(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=date, cvid='TESTSAVE2CURVES')
rate = InterestRate(term='M', numTerms=1, type='Deposit', mid=0.01)
curve.addRate(rate)
curve.save()
此执行会导致另一条曲线并保存另一个速率。
但是,以下执行无效:
def testSave2Curves(self):
date = tgDate(month=9,day=12,year=2011)
curve = InterestRateCurve(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=date, cvid='TESTSAVE2CURVES')
curve.save()
curve = InterestRateCurve.objects.get(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=date, cvid='TESTSAVE2CURVES')
rate = InterestRate(term='M', numTerms=1, type='Deposit', mid=0.01, curve=curve)
curve.addRate(rate)
curve.save()
date1 = tgDate(month=9,day=13,year=2011)
curve1 = InterestRateCurve(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=date1, cvid='TESTSAVE2CURVES')
curve1.save()
curve1 = InterestRateCurve.objects.get(ccy='USD', index='LIBOR', term='M',
numTerms=3, asOf=date1, cvid='TESTSAVE2CURVES')
rate1 = InterestRate(term='M', numTerms=1, type='Deposit', mid=0.01)
curve1.addRate(rate1)
curve1.save()
这会导致保存两条曲线但只保存一个速率。似乎第二个速率会覆盖之前保存的第一个速率。
答案 0 :(得分:1)
问题是rates = []
作为InterestRateCurve
的类变量的规范。由于此定义,InterestRateCurve
的每个对象都访问相同的费率列表。
在示例中创建了第一条曲线和费率后,InterestRateCurve.rates
包含一个创建的费率。然后创建第二条曲线并保存。执行InterestRateCurve.save()
,跳转到except
分支并执行:
for rate in self.rates:
rate.curve = curve
rate.save()
请记住self.rates
(= InterestRateCurve.rates
)包含您的第一个费率?循环将此速率的外键设置为第二条曲线并保存。现在你的第一条曲线已经没有相关的速度了。第一条曲线的速率现在属于第二条曲线。
之后,您创建第二个费率,其属性与您的第一个费率完全相同。由于您在InterestRate
模型中指定了:
class Meta:
unique_together = ('type', 'term', 'numTerms', 'curve')
...只有一种速率具有完全相同的属性。我不确定旧的是否被删除或新的未被保存。但是,结果是数据库中只有一个速率对象,它属于第二条曲线。
希望你明白我的意思。你应该看看Python的pdb
模块。这是一个调试器,它允许您单步执行代码,并且对这些问题非常有帮助。