当 m2m_changed 调用“pre_clear”时如何访问 pk_set?
Posted
技术标签:
【中文标题】当 m2m_changed 调用“pre_clear”时如何访问 pk_set?【英文标题】:how to access pk_set when m2m_changed call with action "pre_clear"? 【发布时间】:2016-02-28 05:43:06 【问题描述】:我想在删除 ManyToMany 字段中的 realtion 时使用m2m_changed
信号。我把这段代码写在models.py
:
class Unit(Model):
# ....
class Package(Model):
# ...
Lesson = ManyToManyField(Unit, blank=True)
def toppings_changed(sender, **kwargs):
if kwargs.get("pk_set") and kwargs.get("action") == "pre_clear":
# get id of lesson to delete and do something with it
m2m_changed.connect(toppings_changed, sender=Packages.Lesson.through)
在删除Package
模型中的Lesson
关系时,我想做一些事情。但是当我删除关系时pre_clear
将调用并且我无法访问pk_set
(它是无)。删除课程模型中的关系时有没有办法访问Unit
id。
【问题讨论】:
【参考方案1】:根据文档:
pk_set ... 对于 pre_clear 和 post_clear 操作,这是 None。https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
【讨论】:
【参考方案2】:-
首先:
m2m_changed
在 多对多 关系的两侧的任何 发生变化时被调用。即some_unit.package_set.clear()
和some_package.Lesson.clear()
都可以触发注册信号。
第二:在pre_clear
状态下,所有关系仍然存在(因为它实际上是pre-clear)。所以你可以像这样看到要删除的内容:
def toppings_changed(sender, reverse, action, **kwargs):
if action == "pre_clear":
if reverse:
# sender is of type Unit
# i.e. current signal is raised by: some_unit.package_set.clear()
packages_to_be_removed = sender.package_set.all()
else:
# sender is of type Package
# i.e. current signal is raised by: some_package.Lesson.clear()
lessons_to_be_removed = sender.Lesson.all()
【讨论】:
我有一段时间对大写的Lesson
感到困惑。它确实是Package
类上的一个字段。
@dhill 你是对的。这不是一个合适的命名。但我只是试图与有问题的例子保持一致。以上是关于当 m2m_changed 调用“pre_clear”时如何访问 pk_set?的主要内容,如果未能解决你的问题,请参考以下文章
删除关系时,Django Python m2m_change 不起作用
如何在 Django 中使 m2m_changed 信号原子化?
GenericRelation 的 Django m2m_changed 信号,有可能吗?