【问题标题】:Django: how to execute code ONLY after the first time a M2M relationship is added?Django:如何仅在第一次添加 M2M 关系后执行代码?
【发布时间】:2013-06-26 11:06:54
【问题描述】:

我试图让 create_reminder_send_message() 在第一次保存 Reminder 对象并保存 Reminder.users 时执行。每次我更新对象时都会执行代码......我错过了什么?我怎样才能完成我想要的?

class Reminder(models.Model):
    METHODS = (
        ('EM', 'Send Email'),
        ('TS', 'Create Dashboard Task'),
        ('ET', 'Both (recommended)')
    )
    info = models.TextField()
    method = models.CharField(max_length=3, choices=METHODS, db_index=True,
                              help_text='''How should I remind the user? (
                              remember that the backend will not be able to
                              send the emails if the users haven't set it up
                              in their profile options)''')
    users = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                   related_name='reminders')
    due_date = models.DateField(blank=True, null=True, db_index=True)
    remind_date = models.DateField(db_index=True)
    sent = models.BooleanField(default=False, db_index=True)
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True,
                                   related_name='created_by')

def create_reminder_send_message(sender, **kwargs):
    '''
    A signal that creates a new "Message" when a reminder is assigned
    to a user or group of users.
    '''
    instance = kwargs.get('instance')
    text = "I have added a new reminder for you. \nActivation date: {0}".format(instance.remind_date)
    message = Message.objects.create(user=instance.created_by,
                    subject='New reminder!', body=text, draft=False)
    message.to = instance.users.all()
    message.received = timezone.now()
    message.save()


models.signals.m2m_changed.connect(create_reminder_send_message, sender=Reminder.users.through)

【问题讨论】:

  • 在信号方法中,你能不能不只做一个instance.users.count() == 0
  • 但我需要将 instance.users.all() 分配给 message.to
  • 我明白了,但在此之前,做一个检查,如果条件通过,就做任何你想做的事情
  • 如果条件通过我什么都不想做。我只想在第一次保存 Reminder 对象后创建消息...但我不能使用 post_save 信号,因为在保存对象后添加了 M2M 关系。
  • @PeterDeGlopper 我想过,但是管理其他任何事情都会很痛苦......我想我可以保留一个 Reminder.counter 字段,每次保存提醒时都会更新,并且仅当 instance.counter == 1 时执行信号回调

标签: django django-signals django-orm m2m


【解决方案1】:

Django 的m2m_changed 信号为您提供action argument。如果actionpre_add,您可以检查您的信号接收器,然后检查是否已经存在提醒。除了删除所有提醒并创建新提醒的情况外,这将起作用 - 不知道您是否可以执行代码。 否则,唯一的可能性是存储额外的数据,例如。您可以在第一次将布尔值设置为True 或将instance 存储在您的Message 对象中,这样您就可以检查消息是否已经存在...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-11
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    相关资源
    最近更新 更多