Django 在模型更新时更新反向外键模型
我有3种型号,客户、公司和产品。产品具有公司的外键、公司和FK帐户。 它们都有一个名为“is_active”的字段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
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)
我需要的是:
父项与子项之间的关系是相反的,而不是子项与父项之间的关系,因此没有字段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循环(也更新了我的答案)你能不能再加上一个循环的例子,我尝试了一些东西,但没有达到预期效果