访问新创建的实例的save方法的m2m关系

时间:2016-09-14 11:41:02

标签: python django django-models m2m

我想在创建订单实例时发送电子邮件(仅限)。在电子邮件模板中,我需要访问m2m关系。不幸的是,似乎m2m关系还没有填充,itemmembership_set.all()方法返回一个空列表。

这是我的代码:

class Item(models.Model):
   ...

class Order(models.Model):
    ...
    items = models.ManyToManyField(Item, through='ItemMembership')

    def save(self, *args, **kwargs):
        pk = self.pk

        super(Order, self).save(*args, **kwargs)

        # If the instance is beeing created, sends an email with the order
        # details.
        if not pk:
            self.send_details_email()

    def send_details_email(self):
        assert len(self.itemmembership_set.all()) != 0

class ItemMembership(models.Model):
    order = models.ForeignKey(Order)
    item = models.ForeignKey(Item)
    quantity = models.PositiveSmallIntegerField(default=1)

1 个答案:

答案 0 :(得分:1)

有些评论建议使用信号。虽然您可以使用信号,特别是m2m_changed信号,但每次修改m2m字段时都会触发。据我所知,发件人模型(在您的样本中,ItemMembership)无法知道关联的Order实例是否刚刚创建。

当然,您可以使用cache框架在调用save()对象的Order时设置临时标志,然后在m2m_changed信号上读取相同的标志并在标志结束时删除标志。缺点是你必须验证这个过程,它胜过使用信号去除东西的目的。

我的建议是从模型中完全删除所有这些电子邮件发送功能。实现它作为辅助函数,然后在成功创建Order对象及其关联的ItemMembership对象后,显式调用辅助函数。恕我直言,它也使调试变得更容易。