【问题标题】:Triggering another model's data to change (M2M) based on this model基于这个模型触发另一个模型的数据变化(M2M)
【发布时间】:2011-03-12 00:03:29
【问题描述】:

基本上,我正在尝试使用来自一个模型的数据来触发另一个模型中的切换。

如果我的发票对象与一个文件相关联,我希望该文件被“锁定”(一个布尔值)。

我发现当我保存发票时,在将其与文件链接后,它不会记录 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)

【问题讨论】:

  • 不确定如何具体解决您的问题,但尝试使用 Django 1.2 的 m2m 更改信号:docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
  • 谢谢斯派克!有趣的是,你应该提到信号,我刚刚删除了它们,因为它们使我的代码变得混乱,我发现重写 save() 和 delete() 更容易。然而,似乎信号提供了更好的控制程度,我可能只是重新启用它们,看看我是否能得到不同的结果。感谢您的建议!

标签: python django django-models many-to-many relationship


【解决方案1】:

删除以下行:

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 方法中,您尝试在将任何 UploadFiles 添加到该集合之前迭代相关集合。我建议为您的 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)。无论如何,这样做甚至是值得的,以避免大量不必要的数据库保存。

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多