django - Django - cascade on other condition
问题描述
I'm using Django and a Postgres database and I have two tables (Authors, Books).
I don't want to enable to deletion of any records, instead to change the boolean of an unseen field called 'active' - a field both tables have. What i'd like to happen is when a user changes an Author's 'active' field to False, all of the books with a FK to this author in the Books table have their 'active' field's also set to False.
In Django, my only options it seems related to deletion, how would I set this up with the models.py file?
解决方案
你可以用信号解决这个问题。在下面的示例中,我假设您的Book
模型具有如下所示的外键字段。
class Book(models.Model):
...
author = models.ForeignKey("Author", related_name="books")
...
选项 1. 使用信号
Author
post_save
连接到信号的示例函数。
from django.db import transaction
from django.db.models.signals import post_save
def update_books_status(sender, instance, created, **kwargs):
with transaction.atomic():
books = Books.objects.select_for_update().filter(author=instance)
for book in books:
book.active = False
book.save()
post_save.connect(update_books_status, sender=Author)
在此示例中,原子事务确保所有更新都在单个数据库查询中运行。n+1
如果您只是在for
循环中运行查询集,这可以避免您遇到的问题。
选项 2. 覆盖save()
另一种可能更好的处理方法是覆盖Author
模型save()
方法。
class Author(models.Model):
...
def save(self, *args, **kwargs):
# Make sure we are not saving a new Author
# And we are saving the Author as inactive
# And we are are saving an Author that was active.
if not self._state.adding and not self.active and self._loaded_values['active']:
self.inactivate_books()
super().save(*args, **kwargs)
def inactivate_books(self):
with transaction.atomic():
books = Books.objects.select_for_update().filter(author=self)
for book in books:
book.active = False
book.save()
推荐阅读
- woocommerce - 商店页面上的 WooCommerce 钩子
- vba - VBA - 拆分和数组
- swift - Xcode 和 Swift 本地化 - 恢复基础语言
- python - 在 Python 中制作移动圆柱体的 3D 动画的最有效方法是什么?
- azure - Azure EventGrid Webhook 超时
- webpack - scripts-webpack-plugin✖「wdm」:错误:ENOENT:'/node_modules/jquery.flot.spline/jquery.flot.spline.js'
- vim - 如何缩写“|” 字符?
- twitter-bootstrap - Bootstrap:如何更改导航栏活动类
- angularjs - 自定义bindhtmlunsafe指令显示html
- java - 在 Logback 日志框架中创建自定义日志级别