【问题标题】:Django: Getting m2m related objects in signalsDjango:在信号中获取 m2m 相关对象
【发布时间】:2016-09-28 11:25:10
【问题描述】:

我有点想看到类似的问题 (Django accessing ManyToMany fields from post_save signal),但仍然看不到如何获取更新的相关对象列表。

例如我有以下型号

class User(models.Model):
    username = models.CharField

class Blog(models.Model):
    user = models.ManyToManyField('User')

现在我通过 django admin 将用户添加到给定的博客。

所以我希望下面的信号将打印所有新用户(我刚刚添加)......但是......我一直得到旧列表:(

@receiver(m2m_changed, sender=Blog.users.through)
def blog_users_change(sender, instance, **kwargs):
     print instance.users.all()

最后一行给出了旧的用户列表instance.users.all()。例如。此处添加的用户不会被反映。

【问题讨论】:

  • 是原码吗?我的意思是,你的 senderBlog.users.through 而你的 m2m 是 Blog.user 而不是 Blog.users

标签: python django


【解决方案1】:

m2m_changed 信号在保存/更新过程的几个阶段被触发,并且有一个 action 参数提供给信号处理程序,告诉您它处于哪个阶段。来自documentation

动作

一个字符串,指示对关系进行的更新类型。这可以是以下之一:

“pre_add” 在将一个或多个对象添加到关系之前发送。

“post_add” 在将一个或多个对象添加到关系后发送。

“pre_remove” 在从关系中删除一个或多个对象之前发送。

“post_remove” 在从关系中删除一个或多个对象后发送。

“pre_clear” 在关系清除之前发送。

“post_clear” 关系清除后发送。

如果您捕获了pre_remove 操作,那么您将获得所有对象之前,其中一些对象已从关系中删除。这就是为什么您看到的用户列表明显没有变化。

在决定做什么之前,您的代码需要检查action。例如:

@receiver(m2m_changed, sender=Blog.users.through)
def blog_users_change(sender, instance, action, **kwargs):
    if action == 'pre_remove':
         # This will give you the users BEFORE any removals have happened
         print instance.users.all()
    elif action == 'post_remove':
         # This will give you the users AFTER any removals have happened
         print instance.users.all()

【讨论】:

  • 我仍然认为 post_add 不允许我看到更新的列表(例如,我正在添加的新用户)
  • 唯一没有得到pk_setUUIDs 的情况是pre_post_clear 信号。
猜你喜欢
  • 2014-12-21
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 2013-08-18
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多