基本上,我试图使用一个模型中的数据来触发另一个模型中的切换。
如果我的发票对象与文件链接,我希望文件被“锁定”(布尔值)。
我发现当我保存发票时,在将其与文件链接后,它没有注册invoice_file.count()是> 0 - 直到下次我打开发票并再次保存。请注意,我在调用super()之后正在进行评估,所以我觉得这最好让人感到困惑。
class Invoice(models.Model):
...
invoice_file = models.ManyToManyField(UploadFile, null = True, blank = True)
def save(self, *args, **kwargs):
print('Invoice: saving!')
super(Invoice, self).save(*args, **kwargs)
print 'invoice_file count: %i' % self.invoice_file.count()
if self.invoice_file.count() > 0:
for invoice_file in self.invoice_file.all():
if(invoice_file.locked_status(1)) != 1: raise Exception('Couldn\'t set file locked status to 1 on file %s' % invoice_file.filename)
这会在UploadFile模型中触发一个函数:
class UploadFile(models.Model):
...
def locked_status(self, stat):
print('Locked status called.')
if stat == 1:
self.locked = True
self.save()
return 1
elif stat == 0:
self.locked = False
self.save()
return 0
def save(self, *args, **kwargs):
print 'UploadFile: Saving!'
super(UploadFile, self).save(*args, **kwargs)
答案 0 :(得分:2)
删除以下行:
if self.invoice_file.count() > 0:
如果您要进行数据库命中,您可以通过检索与发票关联的所有文件来执行此操作。这应该具有检索相关对象的“新鲜”视图的额外好处。
问题可能更深。在保存包含模型之前,无法保存ManyToMany字段。一个例子:
class Post(models.Model):
title = models.CharField(max_length=100)
commenters = models.ManyToManyField(User)
me = User.objects.get(username='Josh')
p = Post(title="ManyToManyExample")
p.commenters.add(me) # error, Post does not yet have an ID.
p.save()
p.commenters.add(me) # success!
您的invoice_file
字段名称不准确。它应该被称为invoice_files
,因为它是一个集合。在您的Invoice.save
方法中,您尝试在将任何UploadFile
添加到该集合之前迭代相关集合。我建议您为Invoice
模型添加方法。
class Invoice(models.Model):
...
def add_invoice_file(self, uploaded_file):
self.invoice_files.add(uploaded_file) # error if the Invoice hasn't been saved yet
for invoice_file in self.invoice_files.all():
status = invoice_file.locked_status(1)
if status != 1:
raise Exception('Blah')
如果发票与大量文件相关联,而不是使用.all()
,则应self.invoice_files.filter(locked=False)
。无论如何,甚至可能值得这样做,以避免大量的数据库保存,这是不必要的。