Django 在模型更新时更新反向外键模型

Django 在模型更新时更新反向外键模型,django,django-models,Django,Django Models,我有3种型号,客户、公司和产品。产品具有公司的外键、公司和FK帐户。 它们都有一个名为“is_active”的字段 class Product(Meta): company = models.ForeignKey(Company, related_name='products', on_delete=models.CASCADE) is_active = models.BooleanField(default=False) class Company(Meta): a

我有3种型号,客户、公司和产品。产品具有公司的外键、公司和FK帐户。 它们都有一个名为“is_active”的字段

class Product(Meta):
    company = models.ForeignKey(Company, related_name='products', on_delete=models.CASCADE)
    is_active = models.BooleanField(default=False)


class Company(Meta):
    account = models.ForeignKey(Account, related_name='account', on_delete=models.CASCADE)
    is_active = models.BooleanField(default=False)  
我需要的是:

  • 当公司处于活动状态变为虚假时,我希望所有与公司相关的产品处于活动状态变为虚假
  • 当帐户处于活动状态变为False时,我希望与该帐户相关的所有公司处于活动状态变为False,并传播到产品
  • 我知道我需要更改保存(或使用post save信号),但我不知道如何选择和更改外键模型,以及如何向下传播多个级别,以防出现帐户错误


    父项与子项之间的关系是相反的,而不是子项与父项之间的关系,因此没有字段FK可用。

    让我向您展示我的解决方案。首先,您应该跟踪对字段的更改(在本例中为“is_active”)。要在模型的init中执行此操作,必须保留缓存值,并在保存时检查值:如果更改,则更新数据库:

    class Company(Meta):
       ...(field definitions)
    
       def __init__(self, *a, **kw):
           super().__init__(*a, **kw):
           self.__original_is_active = self.is_active
    
       def save(self, *a, **kw):
          if self.__original_is_active != self.is_active and self.is_active==False:
              # use raw update to perform better than loop
              self.products.update(is_active=False)
          super().save(*a, **kw)
    
    更新(添加帐户更改代码) 我认为公司模式与账户有外键关系

    class Account(Meta):
        ...(field definitions)
    
        def __init__(self, *a, **kw):
            super().__init__(self, *a, **kw)
            self.__original_is_active = self.is_active
    
        def save(self, *a, **kw):
            if self.__original_is_active != self.is_active and self.is_active == False:
                for company in self.company_set.all():
                    company.is_active = False
                    company.save()
            super().save(*a, **kw)
    
    如果帐户与公司之间存在多人关系,则在save方法中将self.company\u set.all()更改为self.companys.all(),仅此而已


    您的帐户模型将进行类似的更改,但不要忘记使用for循环更新公司,因为“update”方法不会生效,因为它将直接执行SQL并忽略我对公司所做的“init,save”操作(如所说)

    反向关系的实例可在
    模型集访问,例如,对于公司实例,您可以在
    Company\u instance.product\u set
    访问其所有产品。这回答了你的问题吗@petr我可以使用相关名称,而不是默认名称,但作为反向FK,我需要循环通过它们并在子模型上执行保存/更新,以防帐户进一步传播,我尝试了一些东西,但它们不起作用;也许你可以给我一个完整问题的例子,你不需要再进一步了-这两个模型都将覆盖
    save()
    方法,这意味着当你改变一个关系的实例时,其他的将自动传播。谢谢你,所以你是说在帐户的情况下,而不是使用“self.companys.update”(is_active=False)“使用for循环;如果在某些情况下只有一家公司会更新,该怎么办?不使用update()方法,不会调用外键相关对象的save方法。请查看说明相同的文档()。因此,无论您有多少外键相关对象,您都必须使用for循环(也更新了我的答案)你能不能再加上一个循环的例子,我尝试了一些东西,但没有达到预期效果